[ruby-core:119839] [Ruby master Bug#20881] Complex#** returns discontinuous results in Fixnum and Bignum exponents

Issue #20881 has been reported by mame (Yusuke Endoh). ---------------------------------------- Bug #20881: Complex#** returns discontinuous results in Fixnum and Bignum exponents https://bugs.ruby-lang.org/issues/20881 * Author: mame (Yusuke Endoh) * Status: Open * Assignee: mrkn (Kenta Murata) * ruby -v: ruby 3.4.0dev (2024-10-18T02:35:00Z master 9a98b70a50) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- `Complex#**` performs the straightforward calculation when the exponent is Fixnum, but performs the computation in the polar coordinate system when the exponent is Bignum. Therefore, errors accumulate in the former case and not in the latter. ``` (Complex.polar(1, 1) ** 100000000000000).abs #=> 1.0033483420677842 (Complex.polar(1, 1) ** 1000000000000000).abs #=> 1.0339924646874608 (Complex.polar(1, 1) ** 10000000000000000).abs #=> 1.3969270854305682 (Complex.polar(1, 1) ** 100000000000000000).abs #=> 28.29680363011009 (Complex.polar(1, 1) ** 1000000000000000000).abs #=> 329134804659039.0 # ↑ Fixnum # ↓ Bignum (Complex.polar(1, 1) ** 10000000000000000000).abs #=> 1.0 (w/ warning: in a**b, b may be too big) (Complex.polar(1, 1) ** 100000000000000000000).abs #=> 0.9999999999999999 (w/ warning: in a**b, b may be too big) (Complex.polar(1, 1) ** 1000000000000000000000).abs #=> 1.0 (w/ warning: in a**b, b may be too big) ``` It may be good to always calculate them in the polar coordinate. I found this issue when addressing #20811. -- https://bugs.ruby-lang.org/

Issue #20881 has been updated by tompng (tomoya ishida). I slightly expect `(1.0+2.0i)**5` to be exactly `41.0-38.0i` instead of `40.99999999999999-38.00000000000003i` calculated in polar coordinate. Precise value of `Complex.polar(1, 1).abs` is `1.00000000000000002423` (rounded to 1.0). `(Complex.polar(1, 1.11) ** 1000000000000000000000).abs` is `0.0`. `Complex.polar(1, 1.12).abs2` is `1.0000000000000002` (abs is rounded to 1.0) In this case, straightforward calculation and polar coordinate calculation is both equally inaccurate. (https://gist.github.com/tompng/9e3570063ba803d0f54b04b9bd2d2387) I think the only problem is the discontinuous gap. ---------------------------------------- Bug #20881: Complex#** returns discontinuous results in Fixnum and Bignum exponents https://bugs.ruby-lang.org/issues/20881#change-110551 * Author: mame (Yusuke Endoh) * Status: Open * Assignee: mrkn (Kenta Murata) * ruby -v: ruby 3.4.0dev (2024-10-18T02:35:00Z master 9a98b70a50) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- `Complex#**` performs the straightforward calculation when the exponent is Fixnum, but performs the computation in the polar coordinate system when the exponent is Bignum. Therefore, errors accumulate in the former case and not in the latter. ``` (Complex.polar(1, 1) ** 100000000000000).abs #=> 1.0033483420677842 (Complex.polar(1, 1) ** 1000000000000000).abs #=> 1.0339924646874608 (Complex.polar(1, 1) ** 10000000000000000).abs #=> 1.3969270854305682 (Complex.polar(1, 1) ** 100000000000000000).abs #=> 28.29680363011009 (Complex.polar(1, 1) ** 1000000000000000000).abs #=> 329134804659039.0 # ↑ Fixnum # ↓ Bignum (Complex.polar(1, 1) ** 10000000000000000000).abs #=> 1.0 (w/ warning: in a**b, b may be too big) (Complex.polar(1, 1) ** 100000000000000000000).abs #=> 0.9999999999999999 (w/ warning: in a**b, b may be too big) (Complex.polar(1, 1) ** 1000000000000000000000).abs #=> 1.0 (w/ warning: in a**b, b may be too big) ``` It may be good to always calculate them in the polar coordinate. I found this issue when addressing #20811. -- https://bugs.ruby-lang.org/
participants (2)
-
mame (Yusuke Endoh)
-
tompng (tomoya ishida)