ruby-numo / numo-narray

Ruby/Numo::NArray - New NArray class library
http://ruby-numo.github.io/narray/
BSD 3-Clause "New" or "Revised" License
415 stars 41 forks source link

Incorrectly Loading Binary Data? #142

Closed cfis closed 4 years ago

cfis commented 4 years ago

Assume you have the following array of bytes representing the 32 bit integer 2_147_483_647.

bytes = [255, 255, 255, 127]

Now:

binary_string = bytes.pack('C*') value1 = binary_string .unpack('L') => [2147483647]

value2 = Numo::Int32.from_binary(binary_string ).to_a => [2147483647]

They look the same. But they are NOT - at least according to Ruby (version 2.6.5):

value1 == value2 => false

value1.first == value2.first => false

This is on Ruby 2.6.5, Windows 64 bit. ruby -v => ruby 2.6.5p114 (2019-10-01 revision 67812) [x64-mswin64_140]

kojix2 commented 4 years ago

I confirmed that it reproduces on Windows 10 + ruby 2.6.3

require 'numo/narray'

p Numo::Int32::MAX # 2147483647
A = 2_147_483_647

value3 = Numo::Int32[A].to_a
p value3                # [2147483647]
p value3.first          # 2147483647
p value3.first == A     # false
p value3.first + 1      # 1
p value3.first + 2      # 2
p value3.first - 1      # -1
p value3.first + 0.0    # 2147483647.0
p value3.first * 1.0    # 2147483647.0
kojix2 commented 4 years ago
100.times do |i|
  j = (A * (i / 100.0)).floor
  p [j, Numo::Int32[j].to_a.first != j]
end

# ↑ all false
# [1030792150, false]
# [1052266987, false]
# [1073741823, false]
# [1095216659, true]
# [1116691496, true]
# [1138166332, true]
# ↓ all true
(1073741823..1095216659).to_a.bsearch do |i|
  Numo::Int32[i].to_a.first == i
end

I tried the bsearch method to find out from which location the strange behavior start, but segmentation fault error occured.

I get the following results, but I don't know if this is the actual boundary.

p Numo::Int32[1073741823].to_a.first == 1073741823 # true
p Numo::Int32[1073741824].to_a.first == 1073741824 # false

Windows 10 + ruby 2.6.3

kojix2 commented 4 years ago

I wrote that I could reproduce it on Ubuntu, but I couldn't do it now. It may be a misunderstanding. I'm sorry, Tanaka-sensei.

cfis commented 4 years ago

So you can reroduce on windows but not Ubuntu? I haven't tried macos or ubuntu yet. I guess this would be a bug in narray though?

kojix2 commented 4 years ago

That's right. I can reproduce on Windows but not on Ubuntu. I think this is a bug too, but it may take time for @masa16 to solve it.

cfis commented 4 years ago

Great. Thanks for looking into it. Let me know if you need help with testing a fix.

masa16 commented 4 years ago

The commit (https://github.com/ruby-numo/numo-narray/commit/851a2f47cbd2a4c9dcddb6486873ee69b8ea016f) fixes a bug in conversion from C-int to Ruby-Integer, and solves this issue. Thank you for reporting.

cfis commented 4 years ago

Awesome, thanks!