I'd be pleased to link to similar information for other major languages.
See also in Pascal Floating-Point Page.
The Table is formatted with <pre>; thus it can be printed via View Source. On some systems, Ctrl-MouseWheel will change font size.
FPC information from marcov@toad.stack.nl
(Marco van de Voort) :-
Added the Borland compatible compiler
FPC: (0.99.13 development snapshot 3 Nov 1999)
F1 = FPC -So (As TP as possible) F2 = FPC (32-bit TP-ish) F3 = FPC -S2 (Delphi-ish) F4 = FPC -Sd (As Delphi compatible as possible) F5 = FPC -Gp (GNU Pascal mode; largely unfinished)
String=AnsiString can be enabled for all modes afaik with {$H+} in source, or -Sh on the commandline.
TMT information by test with version 3.21/3.30
BYTES Turbo Pascal (inc. BP7) Delphi FPC TMT Version 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 3 byte 1 1 1 1 1 1 1 F 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 shortint - - - 1 1 1 1 F 1 1 1 1 1 1 ? 1 1 1 1 1 1 word - - - 2 2 2 2 F 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 smallint - - - - - - - F 2 2 2 2 2 2 ? - - 2 2 - 2 integer 2 2 2 2 2 2 2 G 2 4 4 4 4 4 ? 2 2 4 4 2 2 cardinal - - - - - - - G 2 4 4 4 4 4 4 4 4 4 4 4 4 longint - - - 4 4 4 4 F 4 4 4 4 4 4 ? 4 4 4 4 4 4 longword - - - - - - - - - - 4 4 4 4 4 4 \ / 4 doubleword \ 4 4 4 4 4 / dword * - - - - - - - - - - - - ? 4 4 int64 - - - - - - - - - - 8 8 8 8 8 8 8 - uint64 - - - - - - - - - - 8 enumerated 1 1 1 1 1 1 1 1 1 ? * set * * * * * * * * * * * real 6 6 6 6 6 6 6 6 6 6 8 8 8 ? 8 8 8 8 8 6 real48 - - - - - - - - - - 6 6 6 6 - - - - - - single - - - 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 double - - - 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 extended - - - 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 comp - - - 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 - currency - - - - - - - - 8 8 8 8 8 8 still in alpha test - variant - - - - - - - ? ? 16 16? 16? 16? 16? (complex) - - - - - - - - - - - - ? ? boolean 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 bytebool - - - - - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 wordbool - - - - - - 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 longbool - - - - - - 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 char 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ansichar - - - - - - - F - 1 1 1 1 1 1 - - - - - - widechar - - - - - - - F - 2 2 2 2 2 2 - - - - - - pointer - - - 4 4 4 4 4 4 4 4 4 4 4 ? ? ? ? ? 4 pchar - - - - - 4+ 4+ 4+ 4+ 4+ 4+ 4+ 4+ 4+ ? ? ? ? ? 4 string - - - 256 256 256 256 256 ? $H $H $H $H $H $H $H $H $H $H 256 string[N] N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 shortstring - - - - - - - ? N+1 N+1 N+1 N+1 N+1 N+1 256 256 256 256 256 256 ansistring 4+H 4+H 4+H 4+H 4+H - longstring - - - - - - - - 4+H 4+H ? ? ? ? still in alpha test - widestring - - - - - - - - 4+H 4+H ? ? ? 4+H still in alpha test - utf8string - - - - - - - - - - 4+H F = Fundamental G = Generic N = Declared Length +H = plus Heap T5.5 = T5 ? TPW1,TPW1.5? BP7 = T7 = TPW7 $H option, 256 or 4+ * For Set, Enumerated, and others, see the manuals; but in Delphi (>1?) no set takes 3 bytes.
Notes :-
E&OE - RSVP with additions or corrections!
Borland's Pascal records are always packed, without padding between fields.
In Delphi, when a record type is not packed, padding is added so that each field begins at an address which is suitably divisible, to optimise access speed. In at least Delphi 6, packing can be affected by the $A directive.
Borland's Pascals |
Delphi | Kylix | .NET | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 1 | 1 | ||
Ordinals | 1 | ?? | size of type (1,2,4,8) | ??? | Some- times 8 |
? | ? | ? | ? | ? | |||
Floats | 4 if size = 4×N; else 2 | ||||||||||||
Short String | 1 | ||||||||||||
Array | as an element of the array | ||||||||||||
Record | as largest alignment in record | ||||||||||||
Set | size of type if 1,2,4; else 1 | ||||||||||||
Others | 4 |
(I have Pascal, D3 and TD2006; I'm told D4 aligns as D3).
Who knows more? RSVP.
Floating-point work is generally not exact.
Borland's Pascal/Delphi Floating-Point Types | ||||||
---|---|---|---|---|---|---|
Type | single | real | double | extended | comp | |
Source | IEEE | Borland | IEEE | IEEE | IEEE | |
Implementation | FPU/Emulate | Software | FPU/Emulate | FPU/Emulate | FPU/Emulate | |
Length, Bytes | 4 | 6 | 8 | 10 | 8 | |
Resolution | 7 sig digits | 11 sig digits | 15 sig digits | 19 sig digits | 1.0 | |
Least > 0, Denorm | 1.4×10-45 | n/a | 5.0×10-324 | 1.9×10-4951 | n/a | |
Least > 0, Normal | 1.2×10-38 | 2.9×10-39 | 2.3×10-308 | 3.4×10-4932 | 1.0 | |
Biggest | 3.4×10+38 | 1.7×10+38 | 1.7×10+308 | 1.1×10+4932 | 2.0+63-1.0 | |
Notation | Sign, Magn. | Sign, Magn. | Sign, Magn. | Sign, Magn. | Two's Comp. | |
Field Pattern | S-E-F | S-F-E | S-E-F | S-E-I-F | S'-F' | |
Field Sizes, bits | 1-8-23 | 1-39-8 | 1-11-52 | 1-15-1-63 | 1-63 | |
Exponent Bias | 127 | 129 | 1023 | 16383 | n/a | |
(uses <sup> : x×x=x2?)
S, S' = Sign ; E = (biased) Exponent ; I = Integer-part (else use 1.); F, F' = Fraction-part The formulae are in the manuals; most are in IEEE standard 754 (& 854?). Note that, as for integers, the sign bit is in the highest byte. The given range of each type, even comp, is for both positive and negative values; zero is also included in all ranges. The range of comp is -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807, matching Int64. According to documentation, in TP4 (&BP7?), comp $8000000000000000 is NaN; in D3, it's -263 In the Field entries of the table, left-to-right corresponds to addresses High to Low; the S and S' bits are always the MSB of the high byte, as for other types |
For all formats, when all fields are zero the number is a valid zero, and not negative. For the detailed interpretation and usage of the fields, for non-normals, Not-A-Numbers, and INFinities, see the language manual.
Delphi's "currency" type is just a 64-bit integer like "comp" - 2's complement - but with an implied decimal point; the I/O unit is Pounds, the actual resolution is one centi-penny.
IEEE 754 is IEC 559.
IEEE Standard 754 has a Web Page, with links.
The page Some Proposals for Revising ANSI/IEEE Std 754-1985 links to information on :-
The draft revisions include "quad precision" floats : the 128 bit format has 112 fraction bits.
It seems that, often but not inevitably, C float is IEEE single, C double is IEEE double, and C long double is IEEE extended. But check for each system.
The standard Pascal/Delphi conversion routines may not be quite as accurate as one might think or wish, especially for extreme cases such as denormals.
See also Bit Representations of Number in JavaScript Miscellany 0.
If a float is to be transferred via a text file, its bit-pattern can be converted, without reference to its construction, to/from printing characters. This can be either in Hex, using twice the storage, or in some larger base: 13 characters out of a set of 72 suffice with a little to spare; 16 out of 32 are *exactly* sufficient, and encode 2.5 bytes to 4.
John Herbster has code for conversion from a float to an exact decimal string, but the result is necessarily often lengthy. For details, try Google, seeking articles dated around and after Christmas 2002; also at Borland CodeCentral.
A float value can be converted, exactly, to/from a moderately-compact fixed-length Hex string that gives a passably readable indication of its value. An Extended has one sign bit, 64 mantissa bits, and 15 exponent bits; so it can be represented by
±F.FFFF FFFF FFFF FFFF H±FFF
in which each Hex digit is shown at its largest value (NaNs, Infs and non-normals need more thought). Here H means "×16^", and the active bits in the last mantissa digit are only those of greater value than the highest "1" bit in the first digit (the position of that "1" encodes two exponent bits).
A test program containing preliminary versions of my conversion routines, working in Pascal 7 and Delphi 3 at least, is available via programs/ as hexfloat.(pas exe zip).
Do IEEE, or other, standards refer to any such thing?
All data formats may be made readable by conversion to text strings, though there may be loss of accuracy for floating-point numbers. Other languages often use the IEEE Single and/or Double float formats, for which cases no conversion is needed.
To prepare data containing 6-byte/10-byte reals for easier reading in another language, use TP or BP or Delphi to read them and convert them to either IEEE Singles/Doubles or to ASCII strings. TP5.5 can be used, and is free; see Borland Pascal Procurement Page. Example :-
var Vin : real { or real48 } ; Vout : double ; ... Vout := Vin ;
To read TP/BP/Delphi 6-byte reals in another language, read them as six bytes and manipulate the bits as needed. Either assemble them into the pattern of the destination type, or use arithmetic to accumulate the value, as in sixbytes.pas. With such methods, rounding errors might cause small differences.
Likewise now to read 10-byte extendeds, tenbytes.pas. Tests for NaN and Inf should be added to it.
Those, and routines for Singles and Doubles (needed if the destination uses a non-standard format), are now together in floatval.pas. Tests for denorm, NaN and Inf should be added to it.
Programs sixbytes.pas tenbytes.pas may, therefore, be withdrawn.
The program also now contains conversions from extended and double to six-byte real which do not use any true float arithmetic; these may be useful for translating into other languages, if there is a need in them to generate the six-byte format.
To be sorted out
The following can be deduced by careful consideration of the details of the floating-point formats given in the printed Pascal and Delphi manuals, which are more detailed than what I have above.
DRAFT
ISTM that it would be useful, for each of the float types, to have a precise verbal statement of exactly which values can be represented exactly.
Types single, real48, and double (AIUI) differ only in the lengths of exponent and mantissa (and in non-standard numbers); extended differs slightly; comp & currency differ.
Best to start with double-likes :-
Parameter * Type \ param : B M L H table * Single 4 24 -127 +127 numbers are * Real48 6 40 -127 +127 GUESSED * Double 8 53 -1023 +1024
One should show that all of the 28B possibilities are included.
I HAVE NOT CHECKED THE VALUES OF M L & H ABOVE; first one should consider the principles. Perhaps 2M-1 should also be listed?
In the floating-point type named, all integers from zero up to the one given, inclusive, can be represented exactly; the next value cannot be :-
Type | Upper Limit of Continuous Exactness | |
---|---|---|
Single | 224 | 16,777,216 |
Real48 | 240 | 1,099,511,627,776 |
Double | 253 | 9,007,199,254,740,992 |
Extended | 264+ | +18,446,744,073,709,551,616 + 5 ??? |
It is a foundation on which one can build true explanations. For
example, a user who has successfully compared constants of values such
as 2.0, 77.0, 64.25 with Doubles of the "same" value, set either from
constants or by exact simple calculation, needs a sound foundation to
understand the result of a calculation equivalent to
const X = 1.3 ; var Y : Double ; begin write(X=Y) end.
That needs to be worked on.
The standard UpCase() function only converts the characters 'a' to 'z'; in each of the various codepages there are various other characters, such as 'æ' and accented ones, that can also be converted. In DOS 4.0 and up, subfunctions of Int21/65 can be used to convert characters, Pascal strings, and ASCIIZ strings; see Ralf Brown's Interrupt List.
Ralf Quint gave, in News, something like :-
function UpCaseAll(C : char) : char ; var Regs : Registers ; begin Regs.AX := $6520 ; Regs.DL := byte(C) ; Intr($21, Regs) ; UpCaseAll := char(Regs.DL) ; end {UpCaseAll} ; procedure UpperAll(var S : string) ; var Regs : Registers ; begin Regs.AX := $6521 ; Regs.DS := Seg(S) ; Regs.DX := Ofs(S)+1 ; Regs.CX := Length(S) ; Intr($21, Regs) ; end {UpperAll} ;
For asm versions, see his news:c.l.p.b :-
Message-ID: <tq8bnugb76jpimli147ujce3cvl47krkfk@4ax.com>
Date: Tue, 03 Sep 2002 23:12:21 -0700
As far as I can see, these interrupts must use array lookup.
for C := #0 to #255 do LoCaseAll[UpCaseAll(C)] := C ;
should be usable as preparation for the reverse operation.
Some Greek characters may be available in both cases; I don't know whether Int 21/65 recognises this.