Issue #11183 has been updated by JesseJohnson (Jesse Johnson).
This behavior still exists in Ruby 3.2.2.
In order to fix this Complex#** would need to handle the special cases of self being 0+1i and 0-1i.
Correct:
```
irb(main):052:0> Complex(0, -1) ** 1000000000000000000
=> (1+0i)
irb(main):053:0> Complex(0, -1) ** 1000000000000000001
=> (0-1i)
irb(main):054:0> Complex(0, -1) ** 1000000000000000002
=> (-1+0i)
irb(main):055:0> Complex(0, -1) ** 1000000000000000003
=> (0+1i)
irb(main):056:0> Complex(0, -1) ** 1000000000000000004
=> (1+0i)
irb(main):057:0> Complex(0, 1) ** 1000000000000000000
=> (1+0i)
irb(main):058:0> Complex(0, 1) ** 1000000000000000001
=> (0+1i)
irb(main):059:0> Complex(0, 1) ** 1000000000000000002
=> (-1+0i)
irb(main):060:0> Complex(0, 1) ** 1000000000000000003
=> (0-1i)
irb(main):061:0> Complex(0, 1) ** 1000000000000000004
=> (1+0i)
```
Suboptimal:
```
irb(main):066:0> Complex(0, -1) ** 10000000000000000000
(irb):66: warning: in a**b, b may be too big
=> (-0.9125701512929312+0.40892018655135703i)
irb(main):067:0> Complex(0, -1) ** 10000000000000000001
(irb):67: warning: in a**b, b may be too big
=> (-0.9125701512929312+0.40892018655135703i)
irb(main):068:0> Complex(0, -1) ** 10000000000000000002
(irb):68: warning: in a**b, b may be too big
=> (-0.9125701512929312+0.40892018655135703i)
irb(main):069:0> Complex(0, -1) ** 10000000000000000003
(irb):69: warning: in a**b, b may be too big
=> (-0.9125701512929312+0.40892018655135703i)
irb(main):070:0> Complex(0, -1) ** 10000000000000000004
(irb):70: warning: in a**b, b may be too big
=> (-0.9125701512929312+0.40892018655135703i)
irb(main):071:0> Complex(0, 1) ** 10000000000000000000
(irb):71: warning: in a**b, b may be too big
=> (-0.9125701512929312-0.40892018655135703i)
irb(main):072:0> Complex(0, 1) ** 10000000000000000001
(irb):72: warning: in a**b, b may be too big
=> (-0.9125701512929312-0.40892018655135703i)
irb(main):073:0> Complex(0, 1) ** 10000000000000000002
(irb):73: warning: in a**b, b may be too big
=> (-0.9125701512929312-0.40892018655135703i)
irb(main):074:0> Complex(0, 1) ** 10000000000000000003
(irb):74: warning: in a**b, b may be too big
=> (-0.9125701512929312-0.40892018655135703i)
irb(main):075:0> Complex(0, 1) ** 10000000000000000004
(irb):75: warning: in a**b, b may be too big
=> (-0.9125701512929312-0.40892018655135703i)
irb(main):076:0> in):070:0> Complex(0, -1) ** 10000000000000000004
=> (-0.9125701512929312-0.40892018655135703i)
```
----------------------------------------
Bug #11183: Cumulative error on Complex::I ** 100000000000000000000000000000000
https://bugs.ruby-lang.org/issues/11183#change-105310
* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
```
p Complex::I ** 100000000000000000000000000000000
```
が、32bit 環境だと、
```
ruby 2.3.0dev (2015-05-21 trunk 50502) [i386-mswin32_110]
t.rb:1: warning: in a**b, b may be too big
(-0.08483712490438944+1.5651333429325577e+32i)
```
こんな感じで、変な値が出ます。
```
# ubuntu 64bit だと
(0.9943722416631883-0.10594264962575697i)
```
できれば、こっちも 1+0i にぴたっとしてるといいのでしょうが。
この問題に対する、うささんのコメント:
> 真面目にコードを読むと、Complex#** は引数(指数)がFixnumでない場合は複素数をいったん極座標形式に変換してからrとθの双方をそれぞれ計算し、最後にf_complex_polarを使ってComplexオブジェクトにしてるのですが、θはFloatなので当然に誤差が蓄積し、という感じです。まあ、誤差が蓄積しなかったとしても、f_complex_polarの中でせっかくθが0°・90°・180°・270°のケースを特別扱いしようとしてるのにdouble値を==で比較してるのでまったく救われそうにない、という感じではありますが。
> θをn倍する計算に対して、nが整数である場合は360°は0°と同じという性質を利用して誤差を蓄積しない計算をすればだいぶマシになるとは思いますが、しかしめんどくさいっすね。
---Files--------------------------------
my_complex.diff (2.09 KB)
--
https://bugs.ruby-lang.org/
Issue #8445 has been updated by JesseJohnson (Jesse Johnson).
I can replicate this in 3.2.2.
----------------------------------------
Bug #8445: IO.open and IO#set_enconding does not support :fallback option
https://bugs.ruby-lang.org/issues/8445#change-105299
* Author: pjmtdw (Haruhiro Yoshimoto)
* Status: Assigned
* Priority: Normal
* Assignee: akr (Akira Tanaka)
* ruby -v: trunk(ruby 2.1.0dev)
----------------------------------------
RubyDoc says that `IO.open` and `IO#set_encoding` supports optional argument defined in `String#encode`.
http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options
In fact, `:invalid, :undef and :replace` works as expected.
However, `:fallback` option does not work neither for `IO.open` and `IO#set_encoding`.
Following is the example code which does not work.
`f(x)` is never called even if hoge.txt contains non convertible character.
```ruby
File.open("./hoge.txt","r:Shift_JIS:utf-8", :fallback => lambda{|x|f(x)}){|f|
...
}
File.open("./hoge.txt"){|f|
f.set_encoding("Shift_JIS","utf-8",:fallback => lambda{|x|f(x)})
...
}
```
I Think this is because `fill_cbuf()` in `io.c` calls `rb_econv_convert()` from `transcode.c` directly.
On the other hand, `fallback_func` is called in `transcode_loop()`, which is called by `str_encode()`.
Since `transcode_loop()` also calls `rb_econv_convert()`, I wrote a small patch which moves some codes from
`transcode_loop()` to `rb_econv_convert()` to fix the problem.
The attached file is the patch. Hope this helps.
---Files--------------------------------
support-fallback-for-io.patch (3.9 KB)
--
https://bugs.ruby-lang.org/