Skip to content
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

Math.pow returns different results between Int and Float exponents #14307

Open
HertzDevil opened this issue Feb 19, 2024 · 0 comments
Open

Math.pow returns different results between Int and Float exponents #14307

HertzDevil opened this issue Feb 19, 2024 · 0 comments

Comments

@HertzDevil
Copy link
Contributor

On non-Windows platforms, Float64#**(Int32) and Float64#**(Float64) are backed by llvm.powi and llvm.pow respectively. The two can sometimes return different results, in particular when dealing with certain subnormal results:

2.0 ** -1024.0 # => 5.562684646268003e-309
2.0 ** -1024   # => 0.0
0.5 ** 1024.0  # => 5.562684646268003e-309
0.5 ** 1024    # => 5.562684646268003e-309

Reduced: (it doesn't matter whether the base value is a constant or the variable x)

class String
  def to_unsafe
    pointerof(@c)
  end
end

lib LibC
  fun printf(fmt : UInt8*, ...) : Int32
end

@[Link("m")]
lib LibM
  fun pow_f64 = "llvm.pow.f64"(value : Float64, power : Float64) : Float64
  fun powi_f64 = "llvm.powi.f64.i32"(value : Float64, power : Int32) : Float64
end

x = 2.0
LibC.printf("2.0 ** -1024.0 # => %e\n", LibM.pow_f64(x, -1024.0))
LibC.printf("2.0 ** -1024   # => %e\n", LibM.powi_f64(x, -1024)) # prints zero
x = 0.5
LibC.printf("0.5 ** 1024.0  # => %e\n", LibM.pow_f64(x, 1024.0))
LibC.printf("0.5 ** 1024    # => %e\n", LibM.powi_f64(x, 1024))

Although there are no guarantees about either form's precision, this could still be a problem since only Windows delegates #**(Int32) to #**(Float64), thus the same code will not print zero when compiled using MSVC. Maybe we should simply drop powi on the other platforms as well?

See also: llvm/llvm-project#65088

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant