digitalmars.D - handling T.min the right way
- Andrei Alexandrescu (See Website For Email) (11/11) Mar 19 2007 A while ago, C++ did the mistake of defining
- Pragma (7/23) Mar 19 2007 No issue here. In fact, I've never used "double.min" for example - I'm ...
- Frits van Bommel (4/5) Mar 19 2007 I was going to suggest this, but then considered that min_positive could...
- Pragma (4/20) Mar 19 2007 PS, the guy you really need to ask is Don. He seems to be the (if not o...
- Frits van Bommel (19/30) Mar 19 2007 ???
- 0ffh (4/5) Mar 20 2007 No, I think it just means the mantissa msb is 1.
- Daniel Keep (36/44) Mar 20 2007 If I remember correctly, there are two kinds of non-infinite, non-nan,
- Lionello Lunesu (6/14) Mar 19 2007 "Andrei Alexandrescu (See Website For Email)"
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (3/5) Mar 19 2007 quite charming :)
- Frits van Bommel (4/12) Mar 19 2007 Epsilon is already used for a related concept:
- Lionello Lunesu (6/19) Mar 19 2007 Huh, I thought it sounded familiar.
- Lionello Lunesu (6/28) Mar 19 2007 Nevermind, I think I get it. epsilon reflects the smallest exponent,
- BCS (3/43) Mar 20 2007 Actually I think that is backwards. Epsilon reflects the number of bits
- Lionello Lunesu (3/42) Mar 20 2007 I think you're right :) Goes to show how bad their names really are :)
- mike (13/15) Mar 19 2007 nd =
- Don Clugston (14/30) Mar 20 2007 It probably wouldn't break a huge amount of D code, but I don't think
- Andrei Alexandrescu (See Website For Email) (8/40) Mar 20 2007 I'm not even discussing the utility of min_positive. All I'm saying is
- Bill Baxter (13/58) Mar 20 2007 Also when you're say trying to find the maximum of a set of numbers it
- Daniel Keep (15/77) Mar 20 2007 I usually cheat and use nan, then change the comparison so that it will
- Frits van Bommel (12/34) Mar 20 2007 I'd use -float.infinity as the initial value. Empty quantifications
- Bill Baxter (5/30) Mar 20 2007 Yeh, I guess that's better. I've just gotten used to working with
- Don Clugston (9/51) Mar 21 2007 Obviously, but are there many other functions like that? Also, you
- Andrei Alexandrescu (See Website For Email) (10/63) Mar 21 2007 There was another example (computing the minimum of a nonempty
- Don Clugston (9/65) Mar 21 2007 Point taken. I'd support this if at the same time, the bizarre out-by-1
- Lars Ivar Igesund (10/67) Mar 21 2007 And what about carrying over that const mess from C++? If const as a key...
- Don Clugston (5/7) Mar 21 2007 Since you ask...
- Andrei Alexandrescu (See Website For Email) (3/10) Mar 21 2007 Ok, now search for !>=. :o)
- Walter Bright (3/10) Mar 21 2007 That's why your opinion on fp issues carries a lot of weight here -
- 0ffh (6/9) Mar 20 2007 Nope, not at all.
- 0ffh (4/5) Mar 20 2007 Sorry for self-reply!
- Don Clugston (10/17) Mar 21 2007 Exactly -- that's the trap.
- 0ffh (4/9) Mar 21 2007 Faster typing than thinking? Sure! :-))))
- Walter Bright (2/10) Mar 20 2007 For floating point types, if x happens to be +-infinity then x+1==x.
- James Dennett (6/17) Mar 20 2007 Or, most likely, even if x happens to be 1E100. I've not
- Bill Baxter (6/24) Mar 20 2007 The cutoff is basically 2^{mantissa bits+1}.
- Bill Baxter (3/28) Mar 20 2007 --bb
- David B. Held (4/15) Mar 21 2007 Wow, that's almost correct transfinite arithmetic. Technically
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
Mar 19 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? AndreiNo issue here. In fact, I've never used "double.min" for example - I'm suprised to hear that it's positive. As much as I'd like to see D embrace camelCase for multi-word things, "foreach_reverse" has pretty much decided that one for us - T.min_positive seems like a good addition to the language as any. I gather this means that we'll also see a t.max_negative to go along with it? -- - EricAnderton at yahoo
Mar 19 2007
Pragma wrote:I gather this means that we'll also see a t.max_negative to go along with it?I was going to suggest this, but then considered that min_positive could also be defined for integer types, while max_negative has no good definition for the unsigned variants.
Mar 19 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? AndreiPS, the guy you really need to ask is Don. He seems to be the (if not one of a handful of) math/FP guru around here. ;) -- - EricAnderton at yahoo
Mar 19 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.??? This statement really surprised me. But it does seems to be what DMD does. The relevant line of the spec (http://www.digitalmars.com/d/property.html [section on floats]): --- .min smallest representable normalized value that's not 0 --- Does "normalized" imply non-negative? I guess I could have expected this behavior if I'd paid better attention to this line though, since it's '0' that is explicitly excluded instead of negative infinity. (Also, it uses "smallest" instead of something like "lowest")The right way is to have T.min always return the minimum value (duh) and define a separate property T.min_positive.Obviously. Since the minimum positive number would be a denormalized value (right?), perhaps a T.min_normalized as well? (or if "normalized" doesn't imply non-negative, min_normalized_positive, though that's getting a bit long...)The question is, would a lot of code be hurt by such a change?I didn't even know this wasn't already how it worked...
Mar 19 2007
Frits van Bommel wrote:Does "normalized" imply non-negative?No, I think it just means the mantissa msb is 1. Happy hacking, 0ffh
Mar 20 2007
0ffh wrote:Frits van Bommel wrote: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/Does "normalized" imply non-negative?No, I think it just means the mantissa msb is 1. Happy hacking, 0ffh
Mar 20 2007
"Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...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.Isn't this value sometimes also called "epsilon"? I think double.epsilon sounds quite nice :) L.
Mar 19 2007
Lionello Lunesu wrote:Isn't this value sometimes also called "epsilon"? I think double.epsilon sounds quite nice :)quite charming :) Luis
Mar 19 2007
Lionello Lunesu wrote:"Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...Epsilon is already used for a related concept: ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)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 :)
Mar 19 2007
Frits van Bommel wrote:Lionello Lunesu wrote: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."Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...Epsilon is already used for a related concept: ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)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 :)
Mar 19 2007
Lionello Lunesu wrote:Frits van Bommel wrote: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.Lionello Lunesu wrote: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."Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...Epsilon is already used for a related concept: ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)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 :)
Mar 19 2007
Lionello Lunesu wrote:Lionello Lunesu wrote:Actually I think that is backwards. Epsilon reflects the number of bits in the mantissa and min_positive reflects the smallest exponent.Frits van Bommel wrote:Nevermind, I think I get it. epsilon reflects the smallest exponent, whereas min_positive represents the reflects the resolution of the mantissa.Lionello Lunesu wrote: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."Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...Epsilon is already used for a related concept: ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)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 :)Both have bad names though. What terminology do mathematicians use for these 'constants'? L.
Mar 20 2007
BCS wrote:Lionello Lunesu wrote:I think you're right :) Goes to show how bad their names really are :) L.Lionello Lunesu wrote:Actually I think that is backwards. Epsilon reflects the number of bits in the mantissa and min_positive reflects the smallest exponent.Frits van Bommel wrote:Nevermind, I think I get it. epsilon reflects the smallest exponent, whereas min_positive represents the reflects the resolution of the mantissa.Lionello Lunesu wrote: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."Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> wrote in message news:45FEE0BC.4000407 erdani.org...Epsilon is already used for a related concept: ".epsilon -- smallest increment to the value 1" (http://www.digitalmars.com/d/property.html)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 :)
Mar 20 2007
Am 19.03.2007, 20:13 Uhr, schrieb Andrei Alexandrescu (See Website For = Email) <SeeWebsiteForEmail erdani.org>:The right way is to have T.min always return the minimum value (duh) a=nd =define a separate property T.min_positive.Maybe min could take an enum as parameter: ' T.min(positive); ' T.min(negative); with a default value so that T.min is still valid. Looks a lot more like= D = and less like PHP :) -mike -- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Mar 19 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? AndreiIt 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?
Mar 20 2007
Don Clugston wrote:Andrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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
Mar 20 2007
Andrei Alexandrescu (See Website For Email) wrote:Don Clugston wrote: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; } } --bbAndrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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
Mar 20 2007
Bill Baxter wrote:Andrei Alexandrescu (See Website For Email) wrote:I usually cheat and use nan, then change the comparison so that it will succeed if 'x' is any real number :P That way, if I give it an empty list, I get nan back instead of float.min, which could be misleading. -- Daniel -- 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/Don Clugston wrote: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; } } --bbAndrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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
Mar 20 2007
Daniel Keep wrote:Bill Baxter wrote:I'd use -float.infinity as the initial value. Empty quantifications should return the identity value[1]. At least, that's what I was taught in "Logic and Set Theory" (not sure if I translated that course name right) as well as several other courses I can't remember the names of right now. You'd still need to make sure your comparison does the right thing for NaNs, if that's important. (I'm pretty sure they didn't cover NaNs in any course :) ) [1]: The identity value of an operator <op> is the value e such that (for all x) e <op> x == x <op> e == x holds. (i.e. for '+' it's 0, for '*' it's 1, and for 'max' it's -infinity)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; } } --bbI usually cheat and use nan, then change the comparison so that it will succeed if 'x' is any real number :P That way, if I give it an empty list, I get nan back instead of float.min, which could be misleading.
Mar 20 2007
Frits van Bommel wrote:Daniel Keep wrote:Yeh, I guess that's better. I've just gotten used to working with languages where there's no portable way to get at nan and infinity constants. But I guess D doesn't have that problem. Yay D! --bbBill Baxter wrote:I'd use -float.infinity as the initial value.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; } } --bbI usually cheat and use nan, then change the comparison so that it will succeed if 'x' is any real number :P That way, if I give it an empty list, I get nan back instead of float.min, which could be misleading.
Mar 20 2007
Andrei Alexandrescu (See Website For Email) wrote:Don Clugston wrote:Obviously, but are there many other functions like that? Also, you really should treat floating point as a special case, anyway, because of the possibility of a NaN. I'd be surprised if the total benefit amounted to more than a few dozen lines of library code. There's also the issue of complex types. Currently, this passes: static assert(creal.max == real.max+1i*real.max); -- which is a little strange.Andrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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.
Mar 21 2007
Don Clugston wrote:Andrei Alexandrescu (See Website For Email) wrote:There was another example (computing the minimum of a nonempty collection). But to me the issue is a tad different: (1) the name is clearly misused; (2) it's easy to fix; (3) not fixing it sends the wrong message ("we carried over whatever was in C++ on numerics"). D takes pride in taking care of minutiae. It's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yet at the same time say, "oh, min? that's not really min. I was kidding."Don Clugston wrote:Obviously, but are there many other functions like that? Also, you really should treat floating point as a special case, anyway, because of the possibility of a NaN.Andrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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.I'd be surprised if the total benefit amounted to more than a few dozen lines of library code. There's also the issue of complex types. Currently, this passes: static assert(creal.max == real.max+1i*real.max);Ouch. Andrei
Mar 21 2007
Andrei Alexandrescu (See Website For Email) wrote:Don Clugston wrote:Point taken. I'd support this if at the same time, the bizarre out-by-1 error in min_exp and max_exp was fixed. My code contains quite a few instances of (real.min_exp/2) because I actually wanted the genuine minimum exponent. Then we could say that all normalised numbers x satisfy pow(2, real.min_exp) <= x < pow(2, real.max_exp+1). Possibly even rename the current real.min to be real.min_normal, since it isn't even the smallest representable value > 0.Andrei Alexandrescu (See Website For Email) wrote:There was another example (computing the minimum of a nonempty collection). But to me the issue is a tad different: (1) the name is clearly misused; (2) it's easy to fix; (3) not fixing it sends the wrong message ("we carried over whatever was in C++ on numerics"). D takes pride in taking care of minutiae. It's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yet at the same time say, "oh, min? that's not really min. I was kidding.Don Clugston wrote:Obviously, but are there many other functions like that? Also, you really should treat floating point as a special case, anyway, because of the possibility of a NaN.Andrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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.
Mar 21 2007
Andrei Alexandrescu (See Website For Email) wrote:Don Clugston wrote:And what about carrying over that const mess from C++? If const as a keyword is to stay - just let it mean constant - nothing else.Andrei Alexandrescu (See Website For Email) wrote:There was another example (computing the minimum of a nonempty collection). But to me the issue is a tad different: (1) the name is clearly misused; (2) it's easy to fix; (3) not fixing it sends the wrong message ("we carried over whatever was in C++ on numerics").Don Clugston wrote:Obviously, but are there many other functions like that? Also, you really should treat floating point as a special case, anyway, because of the possibility of a NaN.Andrei Alexandrescu (See Website For Email) wrote: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.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? AndreiIt 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?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.D takes pride in taking care of minutiae. It's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yet at the same time say, "oh, min? that's not really min. I was kidding."!<>= is in use in Tango as it seems to what is actually happening when looking for NaN :) -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Mar 21 2007
Andrei Alexandrescu (See Website For Email) wrote:It's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yetSince you ask... With a quick grep through 2 directories I found three uses, with <>= being used 12 times. But I'm not normal. <g>.
Mar 21 2007
Don Clugston wrote:Andrei Alexandrescu (See Website For Email) wrote:Ok, now search for !>=. :o) AndreiIt's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yetSince you ask... With a quick grep through 2 directories I found three uses, with <>= being used 12 times. But I'm not normal. <g>.
Mar 21 2007
Don Clugston wrote:Andrei Alexandrescu (See Website For Email) wrote:That's why your opinion on fp issues carries a lot of weight here - you're a professional numerics programmer, and those are unusual.It's odd to have the smorgasbord of floating-point operators that D has (how often did _you_ use !<>=?) yetSince you ask... With a quick grep through 2 directories I found three uses, with <>= being used 12 times. But I'm not normal. <g>.
Mar 21 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
Mar 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... :)
Mar 20 2007
0ffh wrote:0ffh wrote:Exactly -- that's the trap. Also it's not reversible. x++; x--; changes the value of x in many cases: Old x New x real.max real.infinity // overflow 1.2345678e-10 1.2e-10 // loss of precision 1e-50 0 // catastrophic cancellationStandard 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... :)
Mar 21 2007
Don Clugston wrote:0ffh wrote:Faster typing than thinking? Sure! :-)))) (Sorry, couldn't resist!) Greetz, Frank[...] Of course if you have a *very* big number, that might mean it's the same.... sometimes I do faster typing than thinking... :)Exactly -- that's the trap.
Mar 21 2007
0ffh wrote:Don Clugston wrote:For floating point types, if x happens to be +-infinity then x+1==x.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* !
Mar 20 2007
Walter Bright wrote:0ffh wrote:Or, most likely, even if x happens to be 1E100. I've not had the pleasure of working on hardware which supported floating point accurate enough to distinguish 1E100 from 1+1E100. -- JamesDon Clugston wrote:For floating point types, if x happens to be +-infinity then x+1==x.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* !
Mar 20 2007
James Dennett wrote:Walter Bright wrote:The cutoff is basically 2^{mantissa bits+1}. With floats: 2^23 + 1 == 2^23 With double: 2^53 + 1 == 2^53 So it happens for values much less than 1e100. More like 1e7 and 1e16. --bb0ffh wrote:Or, most likely, even if x happens to be 1E100. I've not had the pleasure of working on hardware which supported floating point accurate enough to distinguish 1E100 from 1+1E100. -- JamesDon Clugston wrote:For floating point types, if x happens to be +-infinity then x+1==x.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* !
Mar 20 2007
Bill Baxter wrote:James Dennett wrote:doh! typo -- float has 23 mantissa bits so that should be 24.Walter Bright wrote:The cutoff is basically 2^{mantissa bits+1}. With floats: 2^23 + 1 == 2^230ffh wrote:Or, most likely, even if x happens to be 1E100. I've not had the pleasure of working on hardware which supported floating point accurate enough to distinguish 1E100 from 1+1E100. -- JamesDon Clugston wrote:For floating point types, if x happens to be +-infinity then x+1==x.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* !With double: 2^53 + 1 == 2^53 So it happens for values much less than 1e100. More like 1e7 and 1e16.--bb
Mar 20 2007
Walter Bright wrote:0ffh wrote:Wow, that's almost correct transfinite arithmetic. Technically speaking, 1 + oo == oo, but oo + 1 != oo. IEEE should really fix that. ;> DaveDon Clugston wrote:For floating point types, if x happens to be +-infinity then x+1==x.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* !
Mar 21 2007