Fix high-precision decimal parsing (#116)

This commit is contained in:
Kenny Daniel 2025-09-01 11:24:20 -07:00 committed by GitHub
parent 0609adea03
commit a7bfab0e99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 94 additions and 6 deletions

@ -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)
}
/**

@ -0,0 +1,3 @@
[
[-12345.67]
]

@ -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
}

Binary file not shown.