From 7bd38fd4cd9ffbd9b2fd59d4180775df447fbc4a Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 11:22:48 +0200 Subject: [PATCH 1/8] Convert float16 to float 64 to inline function --- src/float16_conversion.c | 41 ---------------------------------------- src/float16_conversion.h | 41 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 42 deletions(-) delete mode 100644 src/float16_conversion.c diff --git a/src/float16_conversion.c b/src/float16_conversion.c deleted file mode 100644 index ce1bc0f..0000000 --- a/src/float16_conversion.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "float16_conversion.h" - -/* this function is based on the float16->float32 implementation found at - * https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233 - * as well as the process described - * https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ - */ -double float16_to_float64(uint16_t float16_value) { - // float16=1bit: sign, 5bit: exponent, 10bit: fraction - // float64=1bit: sign, 11bit: exponent, 52bit: fraction - const uint64_t sign = float16_value >> 15; - uint64_t exponent = (float16_value >> 10) & 0x1F; - uint64_t fraction = (float16_value & 0x3FF); - uint64_t float64_value; - double res; - if (exponent == 0) { - if (fraction == 0) { - /* zero */ - float64_value = (sign << 63); - } else { - /* denormalised number */ - exponent = 1023 - 14; - while ((fraction & (1 << 10)) == 0) { - exponent--; - fraction <<= 1; - } - fraction &= 0x3FF; - float64_value = (sign << 63) | (exponent << 52) | (fraction << 42); - } - } else if (exponent == 0x1F) { - /* Inf or NaN */ - float64_value = (sign << 63) | (0x7FFULL << 52) | (fraction << 42); - } else { - /* ordinary number */ - float64_value = (sign << 63) | ((exponent + (1023-15)) << 52) | (fraction << 42); - } - - // we do this to avoid GCC warnings about casting uint64_t to double - memcpy(&res, &float64_value, sizeof(double)); - return res; -} diff --git a/src/float16_conversion.h b/src/float16_conversion.h index 7705052..7ad0b26 100644 --- a/src/float16_conversion.h +++ b/src/float16_conversion.h @@ -1,3 +1,42 @@ #include "grumpy.h" -double float16_to_float64(uint16_t float16_value); +/* this function is based on the float16->float32 implementation found at + * https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233 + * as well as the process described + * https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ + */ +static inline double float16_to_float64(uint16_t float16_value) { + // float16=1bit: sign, 5bit: exponent, 10bit: fraction + // float64=1bit: sign, 11bit: exponent, 52bit: fraction + const uint64_t sign = float16_value >> 15; + uint64_t exponent = (float16_value >> 10) & 0x1F; + uint64_t fraction = (float16_value & 0x3FF); + uint64_t float64_value; + double res; + if (exponent == 0) { + if (fraction == 0) { + /* zero */ + float64_value = (sign << 63); + } else { + /* denormalised number */ + exponent = 1023 - 14; + while ((fraction & (1 << 10)) == 0) { + exponent--; + fraction <<= 1; + } + fraction &= 0x3FF; + float64_value = (sign << 63) | (exponent << 52) | (fraction << 42); + } + } else if (exponent == 0x1F) { + /* Inf or NaN */ + float64_value = (sign << 63) | (0x7FFULL << 52) | (fraction << 42); + } else { + /* ordinary number */ + float64_value = (sign << 63) | ((exponent + (1023-15)) << 52) | (fraction << 42); + } + + // we do this to avoid GCC warnings about casting uint64_t to double + memcpy(&res, &float64_value, sizeof(double)); + return res; +} + From 491cfe826a51ad334118151a6a04c08c9273e265 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 11:40:36 +0200 Subject: [PATCH 2/8] Use restrict and avoid recasting pointer --- src/bit64_conversion.c | 37 +++++++++++++++++++++---------------- src/bit64_conversion.h | 4 ++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/bit64_conversion.c b/src/bit64_conversion.c index a6a53fe..19466d8 100644 --- a/src/bit64_conversion.c +++ b/src/bit64_conversion.c @@ -1,17 +1,19 @@ #include "bit64_conversion.h" -void uint32_to_int32(const void* in_buf, size_t n, void* out_buf) { - +void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + + const uint32_t* restrict in = (const uint32_t *)in_buf; + int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; R_xlen_t n_overflow = 0; for (i = 0; i < n; i++) { - if (((uint32_t *)in_buf)[i] > INT_MAX) { - ((int32_t *)out_buf)[i] = INT_MIN; + if (in[i] > INT_MAX) { + out[i] = INT_MIN; n_overflow++; } else { - ((int32_t *)out_buf)[i] = ((uint32_t *)in_buf)[i]; + out[i] = in[i]; } } @@ -24,32 +26,35 @@ void uint32_to_int32(const void* in_buf, size_t n, void* out_buf) { } -void int64_to_int32(const void* in_buf, size_t n, void* out_buf, bool is_signed) { - +void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf, bool is_signed) { + + int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; R_xlen_t n_overflow = 0; R_xlen_t n_underflow = 0; - + if (is_signed) { + const int64_t* restrict in = (const int64_t *)in_buf; for (i=0; i INT_MAX) { - ((int32_t *)out_buf)[i] = INT_MIN; + if (in[i] > INT_MAX) { + out[i] = INT_MIN; n_overflow++; } - else if (((int64_t *)in_buf)[i] < INT_MIN) { - ((int32_t *)out_buf)[i] = INT_MIN; + else if (in[i] < INT_MIN) { + out[i] = INT_MIN; n_underflow++; } else { - ((int32_t *)out_buf)[i] = ((int64_t *)in_buf)[i]; + out[i] = in[i]; } } } else { + const uint64_t* restrict in = (const uint64_t *)in_buf; for (i=0; i INT_MAX) { - ((int32_t *)out_buf)[i] = INT_MIN; + if (in[i] > INT_MAX) { + out[i] = INT_MIN; n_overflow++; } else { - ((int *)out_buf)[i] = ((uint64_t *)in_buf)[i]; + out[i] = in[i]; } } } diff --git a/src/bit64_conversion.h b/src/bit64_conversion.h index a2b8360..738e3fc 100644 --- a/src/bit64_conversion.h +++ b/src/bit64_conversion.h @@ -1,4 +1,4 @@ #include "grumpy.h" -void uint32_to_int32(const void* in_buf, size_t n, void* out_buf); -void int64_to_int32(const void* in_buf, size_t n, void* out_buf, bool is_signed); +void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); +void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf, bool is_signed); From 9e792d91a25f6bfcb227de74f4cd71bcf29d99e7 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 11:24:18 +0200 Subject: [PATCH 3/8] Add float16 benchmarks --- touchstone/script.R | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/touchstone/script.R b/touchstone/script.R index 58a0a71..07323ea 100644 --- a/touchstone/script.R +++ b/touchstone/script.R @@ -24,6 +24,15 @@ touchstone::benchmark_run( n = 100 ) +# float16 +touchstone::benchmark_run( + { + library(grumpy) + }, + read_float16 = read_npy("inst/extdata/test_float16.npy"), + n = 100 +) + # float32 touchstone::benchmark_run( { From 7169cdf62567224ca072718d741a4315a3049f08 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 11:43:09 +0200 Subject: [PATCH 4/8] Add comment on INT_MIN --- src/bit64_conversion.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bit64_conversion.c b/src/bit64_conversion.c index 19466d8..92714f3 100644 --- a/src/bit64_conversion.c +++ b/src/bit64_conversion.c @@ -10,7 +10,7 @@ void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_b for (i = 0; i < n; i++) { if (in[i] > INT_MAX) { - out[i] = INT_MIN; + out[i] = INT_MIN; // NA n_overflow++; } else { out[i] = in[i]; @@ -37,11 +37,11 @@ void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_bu const int64_t* restrict in = (const int64_t *)in_buf; for (i=0; i INT_MAX) { - out[i] = INT_MIN; + out[i] = INT_MIN; // NA n_overflow++; } else if (in[i] < INT_MIN) { - out[i] = INT_MIN; + out[i] = INT_MIN; // NA n_underflow++; } else { out[i] = in[i]; @@ -51,7 +51,7 @@ void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_bu const uint64_t* restrict in = (const uint64_t *)in_buf; for (i=0; i INT_MAX) { - out[i] = INT_MIN; + out[i] = INT_MIN; // NA n_overflow++; } else { out[i] = in[i]; From 549e0b985364226653dba3fcc265000c0b22a3ab Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 13:44:08 +0200 Subject: [PATCH 5/8] Split int64 and uint64 handling --- src/bit64_conversion.c | 81 ++++++++++++++++++++++++------------------ src/bit64_conversion.h | 3 +- src/type_conversion.c | 4 +-- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/bit64_conversion.c b/src/bit64_conversion.c index 92714f3..742427f 100644 --- a/src/bit64_conversion.c +++ b/src/bit64_conversion.c @@ -26,50 +26,63 @@ void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_b } -void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf, bool is_signed) { +void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; R_xlen_t n_overflow = 0; R_xlen_t n_underflow = 0; - if (is_signed) { - const int64_t* restrict in = (const int64_t *)in_buf; - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } - else if (in[i] < INT_MIN) { - out[i] = INT_MIN; // NA - n_underflow++; - } else { - out[i] = in[i]; - } + const int64_t* restrict in = (const int64_t *)in_buf; + for (i=0; i INT_MAX) { + out[i] = INT_MIN; // NA + n_overflow++; } - } else { - const uint64_t* restrict in = (const uint64_t *)in_buf; - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } else { - out[i] = in[i]; - } + else if (in[i] < INT_MIN) { + out[i] = INT_MIN; // NA + n_underflow++; + } else { + out[i] = in[i]; } } - if (n_overflow > 0) { - Rf_warning( - "Integer overflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", - n_overflow - ); - } - if (n_underflow > 0) { - Rf_warning( - "Integer underflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", - n_underflow - ); + if (n_overflow > 0) { + Rf_warning( + "Integer overflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", + n_overflow + ); + } + if (n_underflow > 0) { + Rf_warning( + "Integer underflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", + n_underflow + ); + } + +} + +void uint64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + + const uint64_t* restrict in = (const uint64_t *)in_buf; + int32_t* restrict out = (int32_t *)out_buf; + R_xlen_t i; + R_xlen_t n_overflow = 0; + + for (i=0; i INT_MAX) { + out[i] = INT_MIN; // NA + n_overflow++; + } else { + out[i] = in[i]; } + } + if (n_overflow > 0) { + Rf_warning( + "Integer overflow on %zu elements: converting 64bit unsigned integer to 32bit signed integer resulted in NA values", + n_overflow + ); + } + } diff --git a/src/bit64_conversion.h b/src/bit64_conversion.h index 738e3fc..5bd6caf 100644 --- a/src/bit64_conversion.h +++ b/src/bit64_conversion.h @@ -1,4 +1,5 @@ #include "grumpy.h" void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); -void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf, bool is_signed); +void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); +void uint64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); diff --git a/src/type_conversion.c b/src/type_conversion.c index 051cb67..4451c11 100644 --- a/src/type_conversion.c +++ b/src/type_conversion.c @@ -60,7 +60,7 @@ SEXP type_convert_int(SEXP input, SEXP _n_bytes) { // for now we convert to 32bit int and overflow values are NA_integer int bit64conversion = 0; if (bit64conversion == 0) { - int64_to_int32(raw_buffer, data_length, p_data, true); + int64_to_int32(raw_buffer, data_length, p_data); } } @@ -98,7 +98,7 @@ SEXP type_convert_uint(SEXP input, SEXP _n_bytes) { // for now we convert to 32bit int and overflow values are NA_integer int bit64conversion = 0; if (bit64conversion == 0) { - int64_to_int32(raw_buffer, data_length, p_data, false); + uint64_to_int32(raw_buffer, data_length, p_data); } } From 4c7c40b013c05ea3d014ba7c775786e0812ffbd5 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 14:00:12 +0200 Subject: [PATCH 6/8] Inline bit64 functions as well --- src/bit64_conversion.c | 88 ------------------------------------------ src/bit64_conversion.h | 88 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 91 deletions(-) delete mode 100644 src/bit64_conversion.c diff --git a/src/bit64_conversion.c b/src/bit64_conversion.c deleted file mode 100644 index 742427f..0000000 --- a/src/bit64_conversion.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "bit64_conversion.h" - - -void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { - - const uint32_t* restrict in = (const uint32_t *)in_buf; - int32_t* restrict out = (int32_t *)out_buf; - R_xlen_t i; - R_xlen_t n_overflow = 0; - - for (i = 0; i < n; i++) { - if (in[i] > INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } else { - out[i] = in[i]; - } - } - - if (n_overflow > 0) { - Rf_warning( - "Integer overflow on %zu elements: converting 32bit unsigned integer to 32bit signed integer resulted in NA values", - n_overflow - ); - } - -} - -void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { - - int32_t* restrict out = (int32_t *)out_buf; - R_xlen_t i; - R_xlen_t n_overflow = 0; - R_xlen_t n_underflow = 0; - - const int64_t* restrict in = (const int64_t *)in_buf; - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } - else if (in[i] < INT_MIN) { - out[i] = INT_MIN; // NA - n_underflow++; - } else { - out[i] = in[i]; - } - } - - if (n_overflow > 0) { - Rf_warning( - "Integer overflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", - n_overflow - ); - } - if (n_underflow > 0) { - Rf_warning( - "Integer underflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", - n_underflow - ); - } - -} - -void uint64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { - - const uint64_t* restrict in = (const uint64_t *)in_buf; - int32_t* restrict out = (int32_t *)out_buf; - R_xlen_t i; - R_xlen_t n_overflow = 0; - - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } else { - out[i] = in[i]; - } - } - - if (n_overflow > 0) { - Rf_warning( - "Integer overflow on %zu elements: converting 64bit unsigned integer to 32bit signed integer resulted in NA values", - n_overflow - ); - } - -} diff --git a/src/bit64_conversion.h b/src/bit64_conversion.h index 5bd6caf..631898d 100644 --- a/src/bit64_conversion.h +++ b/src/bit64_conversion.h @@ -1,5 +1,87 @@ #include "grumpy.h" -void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); -void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); -void uint64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf); +static inline void uint32_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + + const uint32_t* restrict in = (const uint32_t *)in_buf; + int32_t* restrict out = (int32_t *)out_buf; + R_xlen_t i; + R_xlen_t n_overflow = 0; + + for (i = 0; i < n; i++) { + if (in[i] > INT_MAX) { + out[i] = INT_MIN; // NA + n_overflow++; + } else { + out[i] = in[i]; + } + } + + if (n_overflow > 0) { + Rf_warning( + "Integer overflow on %zu elements: converting 32bit unsigned integer to 32bit signed integer resulted in NA values", + n_overflow + ); + } + +} + +static inline void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + + int32_t* restrict out = (int32_t *)out_buf; + R_xlen_t i; + R_xlen_t n_overflow = 0; + R_xlen_t n_underflow = 0; + + const int64_t* restrict in = (const int64_t *)in_buf; + for (i=0; i INT_MAX) { + out[i] = INT_MIN; // NA + n_overflow++; + } + else if (in[i] < INT_MIN) { + out[i] = INT_MIN; // NA + n_underflow++; + } else { + out[i] = in[i]; + } + } + + if (n_overflow > 0) { + Rf_warning( + "Integer overflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", + n_overflow + ); + } + if (n_underflow > 0) { + Rf_warning( + "Integer underflow on %zu elements: converting 64bit integer to 32bit integer resulted in NA values", + n_underflow + ); + } + +} + +static inline void uint64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + + const uint64_t* restrict in = (const uint64_t *)in_buf; + int32_t* restrict out = (int32_t *)out_buf; + R_xlen_t i; + R_xlen_t n_overflow = 0; + + for (i=0; i INT_MAX) { + out[i] = INT_MIN; // NA + n_overflow++; + } else { + out[i] = in[i]; + } + } + + if (n_overflow > 0) { + Rf_warning( + "Integer overflow on %zu elements: converting 64bit unsigned integer to 32bit signed integer resulted in NA values", + n_overflow + ); + } + +} From 97fe0a77ba7fa9ad65eab67d333e794fb2c2235f Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 14:08:17 +0200 Subject: [PATCH 7/8] Split loop to enable auto-vectorization --- src/bit64_conversion.h | 58 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/bit64_conversion.h b/src/bit64_conversion.h index 631898d..112000b 100644 --- a/src/bit64_conversion.h +++ b/src/bit64_conversion.h @@ -5,15 +5,16 @@ static inline void uint32_to_int32(const void* restrict in_buf, size_t n, void* const uint32_t* restrict in = (const uint32_t *)in_buf; int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; - R_xlen_t n_overflow = 0; + // This needs to be done in two passes to allow for auto-vectorization of the conversion loop by + // the compiler. + for (i = 0; i < n; i++) { + out[i] = (in[i] > INT_MAX) ? INT_MIN : (int32_t)in[i]; + } + + R_xlen_t n_overflow = 0; for (i = 0; i < n; i++) { - if (in[i] > INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } else { - out[i] = in[i]; - } + n_overflow += (in[i] > INT_MAX); } if (n_overflow > 0) { @@ -27,23 +28,21 @@ static inline void uint32_to_int32(const void* restrict in_buf, size_t n, void* static inline void int64_to_int32(const void* restrict in_buf, size_t n, void* restrict out_buf) { + const int64_t* restrict in = (const int64_t *)in_buf; int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; + + // This needs to be done in two passes to allow for auto-vectorization of the conversion loop by + // the compiler. + for (i = 0; i < n; i++) { + out[i] = (in[i] > INT_MAX || in[i] < INT_MIN) ? INT_MIN : (int32_t)in[i]; + } + R_xlen_t n_overflow = 0; R_xlen_t n_underflow = 0; - - const int64_t* restrict in = (const int64_t *)in_buf; - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } - else if (in[i] < INT_MIN) { - out[i] = INT_MIN; // NA - n_underflow++; - } else { - out[i] = in[i]; - } + for (i = 0; i < n; i++) { + n_overflow += (in[i] > INT_MAX); + n_underflow += (in[i] < INT_MIN); } if (n_overflow > 0) { @@ -66,15 +65,16 @@ static inline void uint64_to_int32(const void* restrict in_buf, size_t n, void* const uint64_t* restrict in = (const uint64_t *)in_buf; int32_t* restrict out = (int32_t *)out_buf; R_xlen_t i; - R_xlen_t n_overflow = 0; - for (i=0; i INT_MAX) { - out[i] = INT_MIN; // NA - n_overflow++; - } else { - out[i] = in[i]; - } + // This needs to be done in two passes to allow for auto-vectorization of the conversion loop by + // the compiler. + for (i = 0; i < n; i++) { + out[i] = (in[i] > INT_MAX) ? INT_MIN : (int32_t)in[i]; + } + + R_xlen_t n_overflow = 0; + for (i = 0; i < n; i++) { + n_overflow += (in[i] > INT_MAX); } if (n_overflow > 0) { @@ -83,5 +83,5 @@ static inline void uint64_to_int32(const void* restrict in_buf, size_t n, void* n_overflow ); } - + } From 139b4ed550ada1c50cf22dc0f1c63a8eea3fd359 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Mon, 3 Aug 2026 14:26:16 +0200 Subject: [PATCH 8/8] Harmonize style --- src/type_conversion.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/type_conversion.c b/src/type_conversion.c index 4451c11..ab2c300 100644 --- a/src/type_conversion.c +++ b/src/type_conversion.c @@ -50,9 +50,8 @@ SEXP type_convert_int(SEXP input, SEXP _n_bytes) { p_data[i] = ((const int8_t *)raw_buffer)[i]; } } else if(n_bytes == 2) { - const int16_t *mock_buffer = (const int16_t *)raw_buffer; for (i = 0; i < data_length; i++) { - p_data[i] = mock_buffer[i]; + p_data[i] = ((const int16_t *)raw_buffer)[i]; } } else if(n_bytes == 4) { memcpy(p_data, raw_buffer, length); @@ -88,9 +87,8 @@ SEXP type_convert_uint(SEXP input, SEXP _n_bytes) { p_data[i] = ((const uint8_t *)raw_buffer)[i]; } } else if(n_bytes == 2) { - const uint16_t *mock_buffer = (const uint16_t *)raw_buffer; for (i = 0; i < data_length; i++) { - p_data[i] = mock_buffer[i]; + p_data[i] = ((const uint16_t *)raw_buffer)[i]; } } else if(n_bytes == 4) { uint32_to_int32(raw_buffer, data_length, p_data); @@ -129,9 +127,8 @@ SEXP type_convert_float(SEXP input, SEXP _n_bytes) { } else if(n_bytes == 4) { - const float *mock_buffer = (const float *)raw_buffer; for (i = 0; i < data_length; i++) { - p_data[i] = (double)mock_buffer[i]; + p_data[i] = (double)((const float *)raw_buffer)[i]; } } else if (n_bytes == 8) {