dylanscott opened a new issue, #81:
URL: https://github.com/apache/arrow-js/issues/81

   ### Describe the enhancement requested
   
   I really love the Arrow project and have gotten an enormous amount of value 
from it, and I realize this is essentially a duplicate of apache/arrow#28804 
but it's been a couple of years and I just want to reiterate how difficult it 
is to properly handle values with the `Decimal` type from the JavaScript 
bindings. All you get is very low-level access to the underlying fixed-width 
buffer and you have to dig through the Arrow source to figure out how to do 
anything non-trivial with them. In my use-case all I need to do is accurately 
stringify them and have just had to fix the 3rd bug I've hit with my 
implementation (handling `scale=0`). Here is what I've arrived at, but I wish I 
had more confidence that there aren't more bugs lurking (there's no way it 
handles Decimal256 properly, but I've never encountered them in the wild):
   
   ```ts
   import { util } from "apache-arrow";
   import { trimEnd } from "lodash";
   
   function formatDecimal(value: Uint32Array, scale: number): string {
     const negative = isNegative(value);
     const sign = negative ? "-" : "";
     if (negative) {
       negate(value);
     }
   
     const str = util.bignumToString(new util.BN(value)).padStart(scale, "0");
     if (scale === 0) {
       return `${sign}${str}`;
     }
   
     const wholePart = str.slice(0, -scale) || "0";
     const decimalPart = trimEnd(str.slice(-scale), "0") || "0";
     return `${sign}${wholePart}.${decimalPart}`;
   }
   
   const MAX_INT32 = 2 ** 31 - 1;
   function isNegative(value: Uint32Array): boolean {
     // 
https://github.com/apache/arrow/blob/3600bd802fbf5eb0c6e00bdae7939bcc3d631eb1/cpp/src/arrow/util/basic_decimal.h#L125
     return value[value.length - 1] > MAX_INT32;
   }
   
   function negate(value: Uint32Array): void {
     // 
https://github.com/apache/arrow/blob/3600bd802fbf5eb0c6e00bdae7939bcc3d631eb1/cpp/src/arrow/util/basic_decimal.cc#L1144
     let carry = 1;
     for (let i = 0; i < value.length; i++) {
       const elem = value[i];
       const updated = ~elem + carry;
       value[i] = updated;
       carry &= elem === 0 ? 1 : 0;
     }
   }
   
   ```
   
   ### Component(s)
   
   JavaScript


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@arrow.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to