diff --git a/src/convert.js b/src/convert.js index be5d897..271d52f 100644 --- a/src/convert.js +++ b/src/convert.js @@ -62,7 +62,7 @@ export function convert(data, columnDecoder) { const factor = 10 ** -scale const arr = new Array(data.length) for (let i = 0; i < arr.length; i++) { - if (data[0] instanceof Uint8Array) { + if (data[i] instanceof Uint8Array) { arr[i] = parseDecimal(data[i]) * factor } else { arr[i] = Number(data[i]) * factor @@ -155,18 +155,20 @@ export function convert(data, columnDecoder) { * @returns {number} */ export function parseDecimal(bytes) { - let value = 0 + if (!bytes.length) return 0 + + let value = 0n for (const byte of bytes) { - value = value * 256 + byte + value = value * 256n + BigInt(byte) } // handle signed const bits = bytes.length * 8 - if (value >= 2 ** (bits - 1)) { - value -= 2 ** bits + if (value >= 2n ** BigInt(bits - 1)) { + value -= 2n ** BigInt(bits) } - return value + return Number(value) } /** diff --git a/test/files/issue115decimal.json b/test/files/issue115decimal.json new file mode 100644 index 0000000..36f350d --- /dev/null +++ b/test/files/issue115decimal.json @@ -0,0 +1,3 @@ +[ + [-12345.67] +] diff --git a/test/files/issue115decimal.metadata.json b/test/files/issue115decimal.metadata.json new file mode 100644 index 0000000..9f99cfb --- /dev/null +++ b/test/files/issue115decimal.metadata.json @@ -0,0 +1,83 @@ +{ + "version": 2, + "schema": [ + { + "repetition_type": "REQUIRED", + "name": "schema", + "num_children": 1 + }, + { + "type": "FIXED_LEN_BYTE_ARRAY", + "type_length": 13, + "repetition_type": "OPTIONAL", + "name": "amount", + "converted_type": "DECIMAL", + "scale": 2, + "precision": 29, + "logical_type": { + "type": "DECIMAL", + "scale": 2, + "precision": 29 + } + } + ], + "num_rows": 1, + "row_groups": [ + { + "columns": [ + { + "file_offset": 0, + "meta_data": { + "type": "FIXED_LEN_BYTE_ARRAY", + "encodings": [ + "PLAIN", + "RLE", + "RLE_DICTIONARY" + ], + "path_in_schema": [ + "amount" + ], + "codec": "SNAPPY", + "num_values": 1, + "total_uncompressed_size": 117, + "total_compressed_size": 121, + "data_page_offset": 33, + "dictionary_page_offset": 4, + "statistics": { + "max": -12345.67, + "min": -12345.67, + "null_count": 0, + "max_value": -12345.67, + "min_value": -12345.67 + }, + "encoding_stats": [ + { + "page_type": "DICTIONARY_PAGE", + "encoding": "PLAIN", + "count": 1 + }, + { + "page_type": "DATA_PAGE", + "encoding": "RLE_DICTIONARY", + "count": 1 + } + ] + } + } + ], + "total_byte_size": 117, + "num_rows": 1, + "file_offset": 4, + "total_compressed_size": 121, + "ordinal": 0 + } + ], + "key_value_metadata": [ + { + "key": "ARROW:schema", + "value": "/////4AAAAAQAAAAAAAKAAwABgAFAAgACgAAAAABBAAMAAAACAAIAAAABAAIAAAABAAAAAEAAAAUAAAAEAAUAAgABgAHAAwAAAAQABAAAAAAAAEHEAAAACAAAAAEAAAAAAAAAAYAAABhbW91bnQAAAgADAAEAAgACAAAAB0AAAACAAAAAAAAAA==" + } + ], + "created_by": "parquet-cpp-arrow version 19.0.1", + "metadata_length": 424 +} diff --git a/test/files/issue115decimal.parquet b/test/files/issue115decimal.parquet new file mode 100644 index 0000000..157948d Binary files /dev/null and b/test/files/issue115decimal.parquet differ