-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-45250: [JS] Fix denominator precision loss and remove unnecessary safe integer check for fractional part #45251
base: main
Are you sure you want to change the base?
Conversation
…eck for fractional part
Thanks for opening a pull request! If this is not a minor PR. Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project. Then could you also rename the pull request title in the following format?
or
See also: |
…eck for fractional part
…eck for fractional part
…eck for fractional part
|
return bigIntToNumber(quotient) + (bigIntToNumber(remainder) / bigIntToNumber(denominator)); | ||
const remainder = negative? -(number % denominator) : number % denominator; | ||
const integerPart = bigIntToNumber(quotient); | ||
const fractionPart = padStart((remainder).toString(), scale); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion, but we should be able to use the String built-in and remove the padStart
below this:
const fractionPart = padStart((remainder).toString(), scale); | |
const fractionPart = `${remainder}`.padStart(scale, '0'); |
function padStart(str: string, targetLength: number) { | ||
while (str.length < targetLength) { | ||
str = '0' + str; | ||
} | ||
return str; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function padStart(str: string, targetLength: number) { | |
while (str.length < targetLength) { | |
str = '0' + str; | |
} | |
return str; | |
} |
if (typeof scale === 'number') { | ||
const denominator = BigInt(Math.pow(10, scale)); | ||
if (typeof scale === 'number' && scale > 0) { | ||
const denominator = BigInt('1' + '0'.repeat(scale)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use padEnd()
here:
const denominator = BigInt('1' + '0'.repeat(scale)); | |
const denominator = BigInt('1'.padEnd(scale + 1, '0')); |
const remainder = negative? -(number % denominator) : number % denominator; | ||
const integerPart = bigIntToNumber(quotient); | ||
const fractionPart = padStart((remainder).toString(), scale); | ||
const sign: string = negative && integerPart === 0 ? '-' : ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const sign: string = negative && integerPart === 0 ? '-' : ''; | |
const sign = negative && integerPart === 0 ? '-' : ''; |
const integerPart = bigIntToNumber(quotient); | ||
const fractionPart = padStart((remainder).toString(), scale); | ||
const sign: string = negative && integerPart === 0 ? '-' : ''; | ||
return Number(`${sign}${integerPart}.${fractionPart}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC coercing via +str
is a bit faster than using the Number constructor. Minifiers will typically do this as well:
return Number(`${sign}${integerPart}.${fractionPart}`); | |
return +`${sign}${integerPart}.${fractionPart}`; |
Rationale for this change
What changes are included in this PR?
This PR uses string constructor for bigint to calculate the power of 10 with scale as the exponent value of the expression.
To Fix precision loss like
Also, we remove the unnecessary safe integer check for the fraction part.
Are these changes tested?
add some unit tests
Are there any user-facing changes?
no