digitalmars.D - We need to clarify if 'real' is the 'default floating point type'
- Don Clugston (47/47) Mar 03 2008 The spec is not quite clear on what 'real' can be and when it should be ...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (10/15) Mar 03 2008 That is quite an understatement! I think it reads something like:
- BCS (12/12) Mar 03 2008 Reply to Don,
- Don Clugston (26/42) Mar 03 2008 Well, IMHO, 'real' is a fine name for the largest without speed penalty....
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (6/9) Mar 03 2008 I think I used "extended" for real80, not that it really matters but.
- Lionello Lunesu (17/17) Mar 03 2008 D should establish some kind of politburo. A group of elders, each with ...
- Ameer Armaly (10/27) Mar 03 2008 I used to think fixed-size types were more optimal, but in retrospect ho...
- Jarrett Billingsley (10/16) Mar 03 2008 I (and my friends) am starting to find D's choice of fixed-size int type...
- Robert Fraser (3/10) Mar 03 2008 I agree, which I why I use ptrdiff_t for all my signed integer needs.
- Lionello Lunesu (7/22) Mar 03 2008 The size_t I get, but I never understood why there's a hash_t that diffe...
- sclytrack (3/6) Mar 04 2008 I think D types should be int8 int32, float32 defined with a number.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (8/15) Mar 04 2008 I'm not sure that it matters which type is the compiler built-in and
- Don Clugston (20/36) Mar 04 2008 Actually, it wouldn't be necessary to create type names for all the diff...
The spec is not quite clear on what 'real' can be and when it should be used. For DMD, 'real' is the 80-bit (actually 79bit) X87 extended floating-point type. This has the following characteristics: a. it is the highest precision floating-point type supported by the hardware; b. it is the highest precision floating-point type which is fast; c. it is almost as fast as double; d. it is the precision used internally for all floating point calculations (And this makes it the only precision which is anomoly-free). e. it is an IEEE floating-point type. In the spec, 'real' is defined as the "largest hardware implemented floating point size (Implementation Note: 80 bits for Intel CPUs)", so we can apparently rely on (a); but unfortunately, that's not enough to give us usage rules. Here are some of the important scenarios: If you are writing exclusively for X87, the usage rule is simple: use float or double for arrays, (for cache efficiency), use real for everything else. Using 'real' instead of 'double' almost never costs you anything, and it frequently provides benefits from the increased precision, and by avoiding anomolies caused by characteristic (d). On AMD64, it's possible to implement a D compiler which only uses SSE floating point, ignoring the X87 entirely. Then 'real' is 'double'. Points 'a'..'e' are all supported, albeit trivially. It makes no difference whether you use 'real' or 'double'. But, a compiler which primarily uses SSE but also supports X87 is also possible. Then 'real'=80 bits, but point 'd' does not apply -- double*double uses 'double' as the intermediate type. Now consider the SPARC (late models only). This has 'real' = quadruple, 128 bits. In theory it's supported by hardware, but many operatons are emulated in software in response to 'unimplemented opcode' traps. Consequently, it's slow. (10X slower than double?). If writing for SPARC, the usage rule is: use 'real' when you truly need the extra precision. Otherwise, use double. On the PowerPC, GDC currently implements 'real' as 'doubledouble' (128 bits) -- with a longer mantissa than 'real' on X87, but with an exponent range the same as 'double'. This isn't a true IEEE type (subnormal numbers don't work properly). Because PowerPC has a FMA instruction, this type is reasonably fast (~3X slower than double?) It satisfies (b) but not (c). Q1. Is this 'doubledouble' acceptable as 'real'? Q2. Is 'real' the 'default type to use, unless you are in a speed-critical code', OR is it 'the type to use when precision is useful and speed is irrelevant' OR something else? IMPLICATIONS: If 'real' is allowed to be relatively slow, then 'double' is the most important precision, and the math library functions need explicit overloads for double precision (since 'double' is guaranteed to be fast on all platforms). Nothing in the compiler needs to change, but we need some more guarantees in the spec for what 'real' can be and how it is allowed to behave.
Mar 03 2008
Don Clugston wrote:The spec is not quite clear on what 'real' can be and when it should be used.That is quite an understatement! I think it reads something like: "`real` is x87 for both platforms that DMD cares about, and can map straightly onto C's long double type for you other weirdos" And then comes "irreal" and "cereal", and makes it surreal...Nothing in the compiler needs to change, but we need some more guarantees in the spec for what 'real' can be and how it is allowed to behave.It would be nice if the spec covered other platforms and compilers, something I don't think is going to happen for D - maybe for D 2.0 ? Once upon a time I got annoyed by all of this (and bools and strings), but then gave up on it and just stopped using the "real" type in D. --anders
Mar 03 2008
Reply to Don, [good stuff removed] this looks like a good cases for a pile of aliases (and the overloads you mentioned). alias for: fast_*, largest with much speed penalty best_*, best supported HW_*, w/ full HW support IEEE_*, IEEE compliant pow2_*, power of 2 length ... these would be used like: best_HW_IEEE_pow2_real (or something like that)
Mar 03 2008
BCS wrote:Reply to Don, [good stuff removed] this looks like a good cases for a pile of aliases (and the overloads you mentioned). alias for: fast_*, largest with much speed penalty best_*, best supported HW_*, w/ full HW support IEEE_*, IEEE compliant pow2_*, power of 2 length ... these would be used like: best_HW_IEEE_pow2_real (or something like that)Well, IMHO, 'real' is a fine name for the largest without speed penalty. It's nice and short, and it sounds like a default type. The only other one you'd want is 'best_real' -- 'real' is viable for that, too, but names like longdouble and longreal come to mind. One workable option would be to split the current 'real' type into real80, doubledouble, and quadruple (depending on the system) and then we had: version(X86) { // more precisely, X86 using the X87 coprocessor typedef real80 real; } else { typedef double real; } version(X86) { typedef real80 longreal; } else version(PPC) { typedef doubledouble longreal; } else version(Sparc){ typedef quadruple longreal; } else { typedef double longreal; } The interesting thing about those types is that they can be emulated on any system. On some systems, multiple options can be implemented efficiently. For example, on Itanium, you have 80-bit reals AND a fma instruction. So you can do real80, doubledouble, the funky internal itanium 81-bit real, and could even do a real80real80 type.
Mar 03 2008
Don Clugston wrote:One workable option would be to split the current 'real' type into real80, doubledouble, and quadruple (depending on the system) and then we had:I think I used "extended" for real80, not that it really matters but. And "quadruple" is a bit long in the tooth, so "quad" rolls better... http://en.wikipedia.org/wiki/Extended_precision http://en.wikipedia.org/wiki/Quad_precision --anders
Mar 03 2008
D should establish some kind of politburo. A group of elders, each with his (..her?) own problem domain. Don should clearly govern the floating point aspects of D and just get to do what he thinks is best. : ) To me, this 'real' problem sounds a lot like the 'int' problem: why should 'int' be established as the default integral type, when it is inefficient on 64-bit hardware (and on 16-bit, 8-bit, .... )? D's very proud of having fixed sized types, and rightly so, but there clearly are situations where size doesn't matter, and shouldn't matter. Of course, there's a minimum limit, when any smaller would just be ridiculous. ...uh... nevermind. So I think we should have 2 new aliases. One for a default int (at least 32-bit) and one for a default float (at least double). On X86/87 these new aliases would map to int and real respectively. Coming up with good names without silly adjectives/underscores will be difficult, though. I, for one, can't come up with any names that 'have it in them' to replace the omnipresent 'int' and 'real'... L.
Mar 03 2008
"Lionello Lunesu" <lionello lunesu.remove.com> wrote in message news:fqi8fc$241f$1 digitalmars.com...D should establish some kind of politburo. A group of elders, each with his (..her?) own problem domain. Don should clearly govern the floating point aspects of D and just get to do what he thinks is best. : ) To me, this 'real' problem sounds a lot like the 'int' problem: why should 'int' be established as the default integral type, when it is inefficient on 64-bit hardware (and on 16-bit, 8-bit, .... )? D's very proud of having fixed sized types, and rightly so, but there clearly are situations where size doesn't matter, and shouldn't matter. Of course, there's a minimum limit, when any smaller would just be ridiculous. ...uh... nevermind. So I think we should have 2 new aliases. One for a default int (at least 32-bit) and one for a default float (at least double). On X86/87 these new aliases would map to int and real respectively. Coming up with good names without silly adjectives/underscores will be difficult, though. I, for one, can't come up with any names that 'have it in them' to replace the omnipresent 'int' and 'real'...I used to think fixed-size types were more optimal, but in retrospect how often do you _really_ care about the maximum value of an int? There are probably some, but more often than not I find myself wanting an integer rather than an integer at least x bits wide. Maybe we just ought to make int whatever type is fastest, and call the current int something different, maybe dword? Disclaimer: I haven't done much serious work in D recently, so odds are I'm missing something.L.
Mar 03 2008
"Ameer Armaly" <ameer.armaly furman.edu> wrote in message news:fqiaio$29mc$1 digitalmars.com...I used to think fixed-size types were more optimal, but in retrospect how often do you _really_ care about the maximum value of an int? There are probably some, but more often than not I find myself wanting an integer rather than an integer at least x bits wide. Maybe we just ought to make int whatever type is fastest, and call the current int something different, maybe dword?I (and my friends) am starting to find D's choice of fixed-size int types a bit irritating since we've been writing an x86-64 kernel in D. I can't tell you how many times we've caused bugs by using int/uint instead of long/ulong. And don't even get me started on why "long" and "ulong" are awful names. (Hint: they're not correct on all platforms.) (they're normal on 64-bit.) (I'll stop now.)
Mar 03 2008
Lionello Lunesu wrote: sounds a lot like the 'int' problem: whyshould 'int' be established as the default integral type, when it is inefficient on 64-bit hardware (and on 16-bit, 8-bit, .... )? D's very proud of having fixed sized types, and rightly so, but there clearly are situations where size doesn't matter, and shouldn't matter. Of course, there's a minimum limit, when any smaller would just be ridiculous. ...uh... nevermind.I agree, which I why I use ptrdiff_t for all my signed integer needs.
Mar 03 2008
"Christopher Wright" <dhasenan gmail.com> wrote in message news:fqibu4$2cfs$1 digitalmars.com...Lionello Lunesu wrote:The size_t I get, but I never understood why there's a hash_t that differs in size.D's very proud of having fixed sized types, and rightly so, but there clearly are situations where size doesn't matter, and shouldn't matter. Of course, there's a minimum limit, when any smaller would just be ridiculous. ....uh... nevermind. So I think we should have 2 new aliases. One for a default int (at least 32-bit) and one for a default float (at least double). On X86/87 these new aliases would map to int and real respectively.For integers, there's size_t / hash_t.I've been trying to forsake my C background for a couple of years now! And it isn't easy :-S L.Coming up with good names without silly adjectives/underscores will be difficult, though. I, for one, can't come up with any names that 'have it in them' to replace the omnipresent 'int' and 'real'...No underscores? Faugh! You forsake your glorious C background! Fie for shame.
Mar 03 2008
I think D types should be int8 int32, float32 defined with a number. Things like int, float without number are all "aliases". [Another Involuntary Feature Request for Java Annotations].So I think we should have 2 new aliases. One for a default int (at least 32-bit) and one for a default float (at least double). On X86/87 these new aliases would map to int and real respectively.
Mar 04 2008
sclytrack wrote:I'm not sure that it matters which type is the compiler built-in and which one is the alias ? At least not enough to change at this point. alias byte int8_t; alias int int32_t; But apparently it is common enough to resurface here every year... Maybe it should be entered into the FAQ, for the language design ? --andersI think D types should be int8 int32, float32 defined with a number. Things like int, float without number are all "aliases".So I think we should have 2 new aliases. One for a default int (at least 32-bit) and one for a default float (at least double). On X86/87 these new aliases would map to int and real respectively.
Mar 04 2008
Don Clugston wrote:The spec is not quite clear on what 'real' can be and when it should be used. For DMD, 'real' is the 80-bit (actually 79bit) X87 extended floating-point type. This has the following characteristics: a. it is the highest precision floating-point type supported by the hardware; b. it is the highest precision floating-point type which is fast; c. it is almost as fast as double; d. it is the precision used internally for all floating point calculations (And this makes it the only precision which is anomoly-free). e. it is an IEEE floating-point type. In the spec, 'real' is defined as the "largest hardware implemented floating point size (Implementation Note: 80 bits for Intel CPUs)", so we can apparently rely on (a); but unfortunately, that's not enough to give us usage rules.Actually, it wouldn't be necessary to create type names for all the different variations of real (except perhaps quad). A possible solution: Change the 'real' keyword into '__real'. Name mangling unchanged. Add version(X86) { alias __real real; } else { alias double real; } into std.object. (Or should the second one be a typedef? I'm not sure). Then we have the design rules: * use 'real' everywhere, except in arrays and I/O. * use __real when you want as much precision as possible, and you don't care how much precision that is. Yes, __real looks like a wierd, non-portable, OS-specific type. And that's what it is. 'real' looks like the type you should use by default.
Mar 04 2008