[#30995] [Bug #3523] win32 exception c0000029 on exit using fibers — B Kelly <redmine@...>

Bug #3523: win32 exception c0000029 on exit using fibers

19 messages 2010/07/02

[#31100] [rubysoc] Queue C-extension patch to come — Ricardo Panaggio <panaggio.ricardo@...>

Hello,

26 messages 2010/07/07
[#31148] Re: [rubysoc] Queue C-extension patch to come — Roger Pack <rogerdpack2@...> 2010/07/09

> As this it my first patch to Ruby, I don't know where to begin with.

[#31320] Re: [rubysoc] Queue C-extension patch to come — Ricardo Panaggio <panaggio.ricardo@...> 2010/07/16

Sorry for leaving this thread for so long. I've tried to finish the

[#31322] Re: [rubysoc] Queue C-extension patch to come — Aaron Patterson <aaron@...> 2010/07/16

On Sat, Jul 17, 2010 at 06:55:35AM +0900, Ricardo Panaggio wrote:

[#31324] Re: [rubysoc] Queue C-extension patch to come — Caleb Clausen <vikkous@...> 2010/07/17

NB: I am Ricardo's mentor for this project.

[#31331] Re: [rubysoc] Queue C-extension patch to come — Benoit Daloze <eregontp@...> 2010/07/17

On 17 July 2010 06:00, Caleb Clausen <vikkous@gmail.com> wrote:

[#31332] Re: [rubysoc] Queue C-extension patch to come — Caleb Clausen <vikkous@...> 2010/07/17

On 7/17/10, Benoit Daloze <eregontp@gmail.com> wrote:

[#31138] Why is there no standard way of creating a String from a char *? — Nikolai Weibull <now@...>

Hi!

14 messages 2010/07/08
[#31146] Re: Why is there no standard way of creating a String from a char *? — Urabe Shyouhei <shyouhei@...> 2010/07/09

(2010/07/09 7:04), Nikolai Weibull wrote:

[#31149] Re: Why is there no standard way of creating a String from a char *? — Nikolai Weibull <now@...> 2010/07/09

On Fri, Jul 9, 2010 at 06:20, Urabe Shyouhei <shyouhei@ruby-lang.org> wrote:

[#31150] Re: Why is there no standard way of creating a String from a char *? — Urabe Shyouhei <shyouhei@...> 2010/07/09

(2010/07/09 18:28), Nikolai Weibull wrote:

[#31217] [Bug #3562] regression in respond_to? — Aaron Patterson <redmine@...>

Bug #3562: regression in respond_to?

14 messages 2010/07/12

[#31269] [Bug #3566] memory leak when spawning+joining Threads in a loop — Eric Wong <redmine@...>

Bug #3566: memory leak when spawning+joining Threads in a loop

14 messages 2010/07/13

[#31399] [Backport #3595] Theres no encoding to differentiate a stream of Binary data from an 8-Bit ASCII string — Dreamcat Four <redmine@...>

Backport #3595: Theres no encoding to differentiate a stream of Binary data from an 8-Bit ASCII string

17 messages 2010/07/21

[#31459] [Bug #3607] [trunk/r28731] Gem.path has disappeared? — Ollivier Robert <redmine@...>

Bug #3607: [trunk/r28731] Gem.path has disappeared?

22 messages 2010/07/23

[#31519] [Bug #3622] Net::HTTP does not wait to send request body with Expect: 100-continue — Eric Hodel <redmine@...>

Bug #3622: Net::HTTP does not wait to send request body with Expect: 100-continue

9 messages 2010/07/28

[ruby-core:31476] [Bug #3589] Converting Bignums to Float for equality checks is wrong

From: Tomasz Wegrzanowski <redmine@...>
Date: 2010-07-25 03:25:45 UTC
List: ruby-core #31476
Issue #3589 has been updated by Tomasz Wegrzanowski.


> > Integer 10 means exactly 10, not everything that would end up as 10 if rounded. 10 == 10.2 #=> false
> but 10 == 10.0. 100000000000000000000000 should == 100000000000000000000000.0
> You know, if you think it should not, you have to persuade us.
> # Assigning this to matz because it turned out to be a design matter.

To me 100000000000000000000000.0 means 100000000000000000000000.to_f,
or "floating point number closest to 100000000000000000000000".
This doesn't have to be exactly 100000000000000000000000.

Some arguments follow.

== Argument from other languages ==

This treatment of float equality seem to be unique to Ruby.
Compare with Python:

print(100000000000000000000000 == 100000000000000000000000.0) #=> False
print( 99999999999999991611392 == 100000000000000000000000.0) #=> True
print(Fraction(1,3) == 1.0/3.0) #=> False
print(Fraction(1,4) == 1.0/4.0) #=> True

With Perl it's more complicated, as Perl's standard number type
switches between native int, native float, and decimal the way Ruby switches
between fixint and bigint - so 1000000000000000000.0 in Perl is
decimal, not float and so exact.

Still, it doesn't follow "equal if converts".
This is the same regardless of $x being decimal or float internally.

my $x = 1000000000000000000;
my $a = Math::BigInt->new('1000000000000000000');
my $b = Math::BigInt->new('1000000000000000001');

print($x == $a->numify() ? "equal" : "not"); #=> equal
print($x == $b->numify() ? "equal" : "not"); #=> equal
print($x == $a ? "equal" : "not"); #=> equal
print($x == $b ? "equal" : "not"); #=> not

A counterexample to this would be C, which is quite explicit that
operations involving different numeric types involve implicit conversion.
It doesn't have bignums, but comparing float vs int or
double vs long long will convert and lose precision before comparison.
It also loses precision this way when comparing integers of
different signedness etc. - this mess is a good example of what
we shouldn't do ;-)

== Argument from sort ==

What would you guess this code to print?

# Build array of bignums, add extra floats
big = 10**50
values  = (1..10).map{|x| big + x}
values += (1..10).map{ big.to_f }
# Make sure it's sorted
values.shuffle!
values.sort!
# Just cleanup for printing
values.reject!{|x| x.is_a?(Float)}
values.map!{|x| x - big}
p values

If you guessed [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
you'd be wrong most of the time.

sort relies on transitivity of <=>, so if <=>
says big.to_f equals both big+1 and big+7,
it naturally assumes big+1 <=> big+7 will also be 0.

It's not a bug in sort - it's how <=> works for everything
except floats.

== Argument from mathematics ==
Ruby has a few equality-like relations - ==, eql?, equal?.
They differ, but they're all (almost) mathematical equivalence relations.
For all three, these can be expected:
* a == a
* a == b iff b == a
* if a == b and b == c then a == c

I can think of one good exception to a == a -
with things like float NaNs and sql nulls - but these really
are more techniques for handling errors than real values.

I really cannot think of a single case where it would
make sense to make equality either non-symmetric,
or non-transitive.

Similar reasoning applies to <=> - normally it defines
partial order between objects:
* a >= b and b >= a only if a == b  
* if a >= b and b >= c then a >= c

Transitivity of equality, and transitivity of partial ordering
seem to be violated only in one case in Ruby - for comparisons
between floats and other numeric types. (and this causes sort
to break).

Can you think of any other type that does something like that?

== Argument from rationals ==
When you have mixed type operations, and one type is bigger,
the most obvious thing to do is simply converting argument
of smaller type to bigger type.

For example you can define pretty much every Rational vs Integer
operation as:

class Rational
  def something(x)
    x = x.to_r if x.is_a?(Integer)
    ...  

And you can do this for Complex operations
and non-complex arguments etc.

You never do it the other way around -
converting to smaller type.
This would be obviously wrong:

class Integer
  def something(x)
    x = x.to_i if x.is_a?(Rational)
    ...  

So why, if Rational can represent every floating
point value (except nans/infinities/negative zero that is),
do rational vs float operations downconvert to float,
instead of upconverting to rational?

I can think of no other such case anywhere.

With bignum vs float, neither is strictly wider than other,
but both can be represented as rationals.

This doesn't mean I want bignum + float to return rationals,
downconversion before returning is perfectly fine.
I just want it to be pretty much equivalent to this:
class Integer
  def +(x)
    if x.is_a?(Float) and x.finite?
      return (self.to_r + x.to_r).to_f
      ...

== Argument from IEEE 754 ==
This .to_r/.to_f above might be puzzling, but look at this.
All basic floating point operations are defined by IEEE 754
standard as mathematically equivalent to this:
  def +(x)
    return (self.to_real + x.to_real).to_f(rounding_mode)
  end  

Where .to_real means conversion to actual mathematical
real number with potentially infinite precision, all extra
bits being 0s.

Of course it's not implemented like that - but the result
is guaranteed to be exactly the same as if it was.

== Other inaccuracies ==
I'm not really terribly bothered by that, only by equality
and <=>, but a lot of operations involving floats and other
types downconvert to float too early and lose precision.

puts(Rational(15,11)*11.0 == 15.0) #=> false
puts((Rational(15,11) * 11.0.to_r).to_f == 15.0) # => true
puts(100000000000000000000000 - 100000000000000000000000.0) #=> 0
puts((100000000000000000000000 - 100000000000000000000000.0.to_i).to_f) #=> 8388608.0

Such precision loss never happens for anything that involves
only floats, or only non-floats. And it really wouldn't be
that difficult to avoid it if we cared, but if even I don't,
I doubt others will.
----------------------------------------
http://redmine.ruby-lang.org/issues/show/3589

----------------------------------------
http://redmine.ruby-lang.org

In This Thread

Prev Next