Skip to content

ReScript force normalizing -0 to 0 #6736

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

Closed
cometkim opened this issue Apr 21, 2024 · 7 comments
Closed

ReScript force normalizing -0 to 0 #6736

cometkim opened this issue Apr 21, 2024 · 7 comments

Comments

@cometkim
Copy link
Member

let a = -0;

produces

var a = 0;

-0 is is an IEEE 754 standard, and JavaScript strictly follows it. This can cause problems in code that relies on this strict distinction, such as Object.is

@cometkim
Copy link
Member Author

Adding here some ChatGPT explanation

Prompt: "Explain why JavaScript distinguishes 0 and -0. Also please let me know if any potential problems may arise when normalizing all -0 to 0"

ChatGPT answer

JavaScript's distinction between 0 and -0 originates from its use of the IEEE 754 standard for floating point arithmetic. In this standard, each number is represented by a sign bit, an exponent, and a significand. Both 0 and -0 are represented with all bits of the exponent and significand as zero, but they differ in their sign bit. 0 has a sign bit of 0 and -0 has a sign bit of 1.

This distinction is useful in certain mathematical computations, particularly those involving limits, derivatives, or integrals in calculus, where the direction of approach towards zero can affect the result. For example, in functions that compute the slope of a tangent or the rate of change, knowing the direction from which zero is approached (positive or negative) can be crucial.

Potential Problems Arising from Normalizing -0 to 0:

  1. Loss of Mathematical Precision: Certain mathematical operations and algorithms rely on the distinction between 0 and -0 to function correctly. For example, the function 1/x approaches infinity as x approaches 0 from the positive side, and negative infinity as x approaches from the negative side. Normalizing -0 to 0 can lead to incorrect results in these cases.

  2. Impact on Sign-sensitive Operations: Functions and operations that are sensitive to the sign of a number, such as Math.sign(), will behave differently if -0 is treated as 0. In JavaScript, Math.sign(-0) returns -1, indicating the negative sign, whereas Math.sign(0) returns 0. Removing the distinction would affect the outcomes of such functions.

  3. Issues in Floating Point Comparisons: In JavaScript, 0 === -0 returns true, but there are some low-level operations or optimized algorithms that might rely on the binary distinction for checks or optimizations. Uniformly treating both as 0 could disrupt these processes.

  4. Implications for Array and Object Keys: In JavaScript, if -0 and 0 are used as keys in objects or arrays, they are treated identically. However, changing how -0 is treated might affect legacy systems or algorithms that have been designed with the existing distinction in mind.

In conclusion, while it might seem redundant or unnecessary to distinguish between 0 and -0, doing so aligns with the precision and requirements of numerical computations in programming and adheres to widely accepted standards in computational mathematics. Removing this distinction can lead to subtle bugs and inaccuracies in complex systems.

@glennsl
Copy link
Contributor

glennsl commented Apr 21, 2024

let a = -0;

This is an int literal. IEEE 754 is the specification for floats. If you make it a float literal it will behave as you expect:

let a = -0.;
var a = -0;

@cometkim
Copy link
Member Author

I see, yet again #6737 😅

@cometkim
Copy link
Member Author

It's subtle that this problem continues to occur when simply casting Int<->Float for interacting with JS bindings

@glennsl
Copy link
Contributor

glennsl commented Apr 21, 2024

See my answer in #6737 (comment). It's really no more surprising than 1.1 being translated to 1. These are different types that represent different sets of values. float to int conversion is by necessity lossy, and there needs to be some kind of mapping between them. You can of course argue that the mapping should be different, but -0 is not a value that can be represented as an int. If you need to make that distinction you should probably use float instead.

@cometkim

This comment was marked as duplicate.

@cometkim
Copy link
Member Author

It seems to be the same topic with #6737, I'm closing this to merge discussions. I will move my last comment.

@cometkim cometkim closed this as not planned Won't fix, can't repro, duplicate, stale Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants