March 20, 2007
Lionello Lunesu wrote:
> Frits van Bommel wrote:
>> Lionello Lunesu wrote:
>>> "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45FEE0BC.4000407@erdani.org...
>>>> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
>>>
>>> Isn't this value sometimes also called "epsilon"? I think double.epsilon sounds quite nice :)
>>
>> Epsilon is already used for a related concept:
>> ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)
> 
> Huh, I thought it sounded familiar.
> 
> So epsilon is such that 1.0+epsilon!=1.0, and the 'min' we're talking about is such that 0.0+min_positive!=0.0 ? I didn't know these were both useful values.... I wonder how they're actually being used.
> 
> L.

Nevermind, I think I get it. epsilon reflects the smallest exponent, whereas min_positive represents the reflects the resolution of the mantissa.

Both have bad names though. What terminology do mathematicians use for these 'constants'?

L.
March 20, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> A while ago, C++ did the mistake of defining std::numeric_limits<T>::min() with a different semantics for floating-point types than for integral types. That hurt generic numeric code a lot.
> 
> D has taken over the same mistake: T.min means the smallest value of the type, except for floating-point types, where it means the smallest positive value.
> 
> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
> 
> The question is, would a lot of code be hurt by such a change?
> 
> 
> Andrei

It probably wouldn't break a huge amount of D code, but I don't think there would be many cases where T.min for a floating point type would be useful. More significant is the problems involved in converting from C or Fortran code to D.

On a more profound level...
I'm not aware of many cases where it's possible to treat integer and floating-points generically. People often try, but usually the code is incorrect for the floating point types, since the semantics are completely different. (For example, I don't know why x++ is legal for floating point types; I think it's just a newbie trap; you have no guarantee that x++ is different to x).

What type of generic numeric code did you have in mind? What are the benefits which would come by such a change?
March 20, 2007
Don Clugston wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> A while ago, C++ did the mistake of defining std::numeric_limits<T>::min() with a different semantics for floating-point types than for integral types. That hurt generic numeric code a lot.
>>
>> D has taken over the same mistake: T.min means the smallest value of the type, except for floating-point types, where it means the smallest positive value.
>>
>> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
>>
>> The question is, would a lot of code be hurt by such a change?
>>
>>
>> Andrei
> 
> It probably wouldn't break a huge amount of D code, but I don't think there would be many cases where T.min for a floating point type would be useful. More significant is the problems involved in converting from C or Fortran code to D.

I'm not even discussing the utility of min_positive. All I'm saying is that if you say "min", you should return "min", particularly when others do exactly that.

> On a more profound level...
> I'm not aware of many cases where it's possible to treat integer and floating-points generically. People often try, but usually the code is incorrect for the floating point types, since the semantics are completely different. (For example, I don't know why x++ is legal for floating point types; I think it's just a newbie trap; you have no guarantee that x++ is different to x).
> 
> What type of generic numeric code did you have in mind? What are the benefits which would come by such a change?

Trivially simple: the min and max functions. For min, the code picks the type with the smallest .min. For max, the code picks the type with the largest .max.


Andrei
March 20, 2007
Lionello Lunesu wrote:
> Lionello Lunesu wrote:
> 
>> Frits van Bommel wrote:
>>
>>> Lionello Lunesu wrote:
>>>
>>>> "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45FEE0BC.4000407@erdani.org...
>>>>
>>>>> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
>>>>
>>>>
>>>> Isn't this value sometimes also called "epsilon"? I think double.epsilon sounds quite nice :)
>>>
>>>
>>> Epsilon is already used for a related concept:
>>> ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)
>>
>>
>> Huh, I thought it sounded familiar.
>>
>> So epsilon is such that 1.0+epsilon!=1.0, and the 'min' we're talking about is such that 0.0+min_positive!=0.0 ? I didn't know these were both useful values.... I wonder how they're actually being used.
>>
>> L.
> 
> 
> Nevermind, I think I get it. epsilon reflects the smallest exponent, whereas min_positive represents the reflects the resolution of the mantissa.

Actually I think that is backwards. Epsilon reflects the number of bits in the mantissa and min_positive reflects the smallest exponent.

> 
> Both have bad names though. What terminology do mathematicians use for these 'constants'?
> 
> L.
March 20, 2007
Don Clugston wrote:
> completely different. (For example, I don't know why x++ is legal for floating point types; I think it's just a newbie trap; you have no guarantee that x++ is different to x).

Nope, not at all.
Standard C defines that after "x++" x is incremented by one, exactly -
*even for fp types* !

Happy hackimg,

	0ffh
March 20, 2007
Frits van Bommel wrote:
> Does "normalized" imply non-negative?

No, I think it just means the mantissa msb is 1.

Happy hacking,

	0ffh
March 20, 2007
0ffh wrote:
> Standard C defines that after "x++" x is incremented by one, exactly -

Sorry for self-reply!
Of course if you have a *very* big number, that might mean it's the same.... sometimes I do faster typing than thinking... :)

March 20, 2007
BCS wrote:
> Lionello Lunesu wrote:
>> Lionello Lunesu wrote:
>>
>>> Frits van Bommel wrote:
>>>
>>>> Lionello Lunesu wrote:
>>>>
>>>>> "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45FEE0BC.4000407@erdani.org...
>>>>>
>>>>>> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
>>>>>
>>>>>
>>>>> Isn't this value sometimes also called "epsilon"? I think double.epsilon sounds quite nice :)
>>>>
>>>>
>>>> Epsilon is already used for a related concept:
>>>> ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)
>>>
>>>
>>> Huh, I thought it sounded familiar.
>>>
>>> So epsilon is such that 1.0+epsilon!=1.0, and the 'min' we're talking about is such that 0.0+min_positive!=0.0 ? I didn't know these were both useful values.... I wonder how they're actually being used.
>>>
>>> L.
>>
>>
>> Nevermind, I think I get it. epsilon reflects the smallest exponent, whereas min_positive represents the reflects the resolution of the mantissa.
> 
> Actually I think that is backwards. Epsilon reflects the number of bits in the mantissa and min_positive reflects the smallest exponent.

I think you're right :) Goes to show how bad their names really are :)

L.
March 20, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Don Clugston wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> A while ago, C++ did the mistake of defining std::numeric_limits<T>::min() with a different semantics for floating-point types than for integral types. That hurt generic numeric code a lot.
>>>
>>> D has taken over the same mistake: T.min means the smallest value of the type, except for floating-point types, where it means the smallest positive value.
>>>
>>> The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.
>>>
>>> The question is, would a lot of code be hurt by such a change?
>>>
>>>
>>> Andrei
>>
>> It probably wouldn't break a huge amount of D code, but I don't think there would be many cases where T.min for a floating point type would be useful. More significant is the problems involved in converting from C or Fortran code to D.
> 
> I'm not even discussing the utility of min_positive. All I'm saying is that if you say "min", you should return "min", particularly when others do exactly that.
> 
>> On a more profound level...
>> I'm not aware of many cases where it's possible to treat integer and floating-points generically. People often try, but usually the code is incorrect for the floating point types, since the semantics are completely different. (For example, I don't know why x++ is legal for floating point types; I think it's just a newbie trap; you have no guarantee that x++ is different to x).
>>
>> What type of generic numeric code did you have in mind? What are the benefits which would come by such a change?
> 
> Trivially simple: the min and max functions. For min, the code picks the type with the smallest .min. For max, the code picks the type with the largest .max.
> 
> 
> Andrei


Also when you're say trying to find the maximum of a set of numbers it can be handy to initialize the 'current_max' to the smallest number possible.

float max_val = float.min; // want the new meaning here
int max_idx = -1;
foreach(i,x; bunch_o_floats) {
   if (x<max_val) {
       max_val=x;
       max_idx=i;
   }
}

--bb
March 21, 2007

0ffh wrote:
> Frits van Bommel wrote:
>> Does "normalized" imply non-negative?
> 
> No, I think it just means the mantissa msb is 1.
> 
> Happy hacking,
> 
>     0ffh

If I remember correctly, there are two kinds of non-infinite, non-nan, non-zero IEEE floating point numbers: normalised and denormalised numbers.

Normal numbers are ones where, like 0ffh said, the number starts with an implicit '1'.  Basically, with IEEE, if you wanted to store the binary number 0b1.0101001, you would *actually* store the '0101001' part: every binary number must has a leading '1' at *some* point, otherwise it'd be zero :)

Now, the other kind of number, a denormal, comes about when your number is so close to zero that IEEE runs out of full-precision numbers.  So what happens here is that IEEE basically starts representing the number using less and less bits, trying to prevent underflow (or overflow if you're using negative numbers) to zero.[1]

This is useful where you're doing a calculation with numbers very close to zero.  The result might be a normalised number, but the intermediates are denormalised.  With support for denormal numbers, you get (approximately) the correct, non-zero result.  Without them, you get zero.

IEEE is pretty interesting, in how much thought and care went into how we represent numbers.  You can read more about Denormal numbers on Wikipedia[2].  There's a link to Kahan's site, but the server seems to be down atm.

	-- Daniel

[1] Incidentally, some people working on the IEEE spec felt that the whole subnormal thing was a waste of time, that they couldn't be implemented efficiently and that these numbers should just automatically round to zero.  Thankfully, Kahan and Intel convinced them otherwise :)

[2] http://en.wikipedia.org/wiki/Denormal

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/