Talk:Single-precision floating-point format

message: The C++ standard library, as an example, will report the max and min exponents as (-125,+128) and assume that the mantissa is in the range (0.5,1).  This article assumes that the exponent is between (-126,127) and that the mantissa is in the range (1,2).  Although either method gets the same answer, the one given in the article does not match standard usage.  The article should make this clear.  —Preceding unsigned comment added by 71.104.122.200 (talk) 03:12, 13 February 2008 (UTC)
replies: text: The values in the article are those given in the IEEE 754 standard (1985), which the article calls out in the first paragraph.  That is the standard for floating-point arithmetic. What clarification(s) would you like to see? mfc (talk) 20:36, 22 February 2008 (UTC)
replies: text: Actually, it matters, because some cstdlib functions will return the raw exponent/mantissa. - Richard Cavell (talk) 05:42, 17 December 2010 (UTC)
replies: text: Well the discrepancy seems to resolve itself, when one looks up what std::numeric_limits<float>::min_exponent actually returns. Quoting from cppreference.com "The value of std::numeric_limits<T>::min_exponent is the lowest negative number n such that r^{n-1}, where r is std::numeric_limits<T>::radix, is a valid normalized value of the floating-point type T". Similar for max_exponent. That seems to imply that one needs to shift (-125,+128) to (-126,127), which are precisely the smallest and largest exponents not used for representing special values in IEEE. The same definition holds for the macros FLT_MIN/MAX_EXPONENT from <float.h> in C. InfoBroker2020 (talk) 10:13, 15 May 2021 (UTC)
thread_title:  Exponent/mantissa ranges are inconsistent with other sources 

message: Can someone check this for me: "The true significand includes 23 fraction bits to the right of the binary point and an implicit leading bit (to the left of the binary point) with value 1 unless the exponent is stored with all zeros."
Is the "exponent is stored with all zeros" part correct? - Richard Cavell (talk) 05:43, 17 December 2010 (UTC)
replies: text: So it's definitely the case that there is no implicit bit when, and only when, the exponent, and only the exponent, is exactly 0? - Richard Cavell (talk) 07:53, 24 December 2010 (UTC)
replies: text: The original statement is correct.  For IEEE754, there is no implicit bit for zero or any of the denormalized representations, all of which have zero exponents.  For pre-754 formats, there might not be an implicit bit at all.  DEC floating formats used an explicit most significant bit, as did most mainframes.  There are also exceptional cases of no implicit bit for the various types of NaNs, and the two infinities:  in those the exponent has all bits set.  Here is a good summary.  —EncMstr (talk) 18:11, 24 December 2010 (UTC)

text: There were several issues. In particular, "all non-zero binary numbers start with a 1" is wrong for subnormals (but "start with" is rather ambiguous). Moreover, your changes did not follow the encyclopedic style (e.g. do not use "that's" or "we"). I've just edited the article to correct ambiguities and give some details; more details are available via internal links. Regards, — Vincent Lefèvre (talk) 13:59, 22 April 2024 (UTC)
replies: text: Thanks for the clarification! I see that my edit didn't really feel very wikipedia-ish but it is just true that the first significant digit of all non-zero binary numbers is a 1. IEE754 doesn't start its mantissa with a 1 for all non-zero binary numbers though so I can understand why that wouldn't make sense to have on the page. I think I will make one (hopefully) final edit to that paragraph to make it flow a bit nicer when you read it, but if I accidentally change its meaning please tell me or revert it. sent by TheGnuGod (talk) at  19:57, 24 April 2024 (UTC)
replies: text:  The leading bit of the significand is 1 only for normal numbers. Subnormal numbers are nonzero numbers for which the leading bit is 0. Note that the IEEE 754 standard says: "A decimal or subnormal binary significand can also contain leading zeros, which are not significant." — Vincent Lefèvre (talk) 00:49, 26 April 2024 (UTC)
replies: text: That is literally what I said. Your message and my message contain exactly the same information, I just didn't use the word subnormal. I accounted for the fact that subnormal numbers start the significand with zero(s) but (like IEEE said) that those zero(s) are not significant. Moreover, I wrote a whole sentence about that, but I suppose you didn't read it for some reason? Kind regards, I guess. sent by TheGnuGod (talk) at  16:10, 26 April 2024 (UTC)
replies: text:  These zeros are not significant, but they are part of the significand, and this is what matters here, in a section dealing with the representation and encoding. — Vincent Lefèvre (talk) 21:45, 26 April 2024 (UTC)
replies: text: I said that as well. You have now failed to read my message twice in a row, telling me I did not say something that I clearly did. I said "IEE754 doesn't start its mastissa with a 1 for all non-zero binary numbers though so I can understand why that wouldn't make sense to have in the article." Please read next time, it is quite helpful when communicating in text. sent by TheGnuGod (talk) at  09:36, 27 April 2024 (UTC)
thread_title:  When the implicit bit doesn't exist 

message: The Section on converting Decimal to Binary32 is really useful, but hard to find tucked in here on the single-precision page. It would be nice if someone could expand it to the general case and put it on the main floating point page.  — Preceding unsigned comment added by Canageek (talk • contribs) 20:38, 15 December 2011 (UTC)
thread_title:  Adding conversion to the main article? 

message: PASCAL float types are "REAL" or additionally "LONGREAL" if there must be types that are different in precision, just like in C they are (long) float.  Single, double etc are names from IEEE specs, and are not part of PASCAL the language, but machines specific identifiers.
I didn't correct it in the main article to avoid confusion (specially since in some popular compilers REAL was typically mapped to softfpu, and single/double were mapped to hardware fpu).
88.159.71.34 (talk) 12:04, 30 June 2012 (UTC)
thread_title:  PASCAL 

message: "Single-precision floating-point format is a computer number format that occupies 4 bytes (32 bits) in computer memory and represents a wide dynamic range of values by using a floating point."
Does this really mean 4 bytes? Won't 4 octets be less ambiguous?  — Preceding unsigned comment added by 112.119.94.80 (talk) 21:20, 7 August 2012 (UTC)
replies: text: It is a reasonable question.  Byte is certainly much better known whereas octet is, as far as I know, mostly used in RFCs.  Since IEEE 754 was standardized and adopted well after the ascension of the eight bit byte, it seems to me we serve our readers better by calling it a byte.  I would not object to a note which specifies that a byte here means eight bit byte or octet.  Maybe it is even clearer to omit bytes altogether, specifying only bits?  —EncMstr (talk) 23:26, 7 August 2012 (UTC)
replies: text: What would such a footnote add? You can already see it's a 32-bit value because it actually literally says so. I think the lead is crystal clear on this matter.  — Preceding unsigned comment added by 82.139.82.82 (talk) 10:42, 16 September 2015 (UTC)
thread_title:  Number of "bytes" 

message: For a single precision floating point in decimal presentation, it was said only 7 digts are significant? but in the article, it is not mentioned, not to mention why it is so. Jackzhp (talk) 17:50, 17 March 2013 (UTC)
thread_title: # of Significant Digits

message: The section on decimal-to-binary conversion is unclear on a few important points:
# How exactly is a fractional component translated into a sequence of bits?I was unable to figure out what was meant by "multiply the fraction by 2, take the integer part and repeat with the new fraction by 2" until a different source provided a clearer explanation. It appears to be copyrighted, so I won't repeat its content here. Basically, the conversion process boils down to:
\begin{align}
.6875 \times 2 & = 1.375 & \Rightarrow 1 \\
.375 \times 2 & = 0.75 & \Rightarrow 0 \\
.75 \times 2 & = 1.5 & \Rightarrow 1 \\
.5 \times 2 & = 1.0 & \Rightarrow 1
\end{align}
\quad \text{therefore:} \quad .6875 = 1011
Or, to put it in JavaScript:
let precision = 23;
let fraction = 0.6875;
let bits = 0;
for(let i = 0; fraction && i <= precision; ++i){
	fraction *= 2;
	const int = ~~fraction; // Discard fraction
	bits |= int << (precision - i++);
	fraction -= int;
}
bits === 0b100010100000000000000000;
None of this was apparent from reading (and re-reading) the explained procedure.
# Is the above translation performed before or after normalisation?If after, why is normalisation not explained first?
# How is the exponent adjusted after normalising?Given a number like , we end up with an exponent of  and a significand of  (). According to the article,  should be normalised into , implying the exponent of  should be incremented by 2 to compensate (-3 + 2 = -1). Based on my own observations and tinkering, it appears the exponent should be decremented instead (-3 - 2 = -5), although my understanding is still shaky at best. Could anybody clarify?
Moreover, the section in question is poorly-structured and littered with redundant language. Conversely, the binary-to-decimal section is clear and concise, enough so that I was able to implement it in JavaScript using no other references. It might benefit the article to rewrite the decimal-to-binary section completely.
--OmenBreeze (talk) 09:50, 23 February 2020 (UTC)
replies: text: Both sections are very unclear, WP:OR, and even incorrect. They should be removed. In your JavaScript code, if you mean bytesToFloat32, then you're not converting to decimal, but to binary. That's very different. Vincent Lefèvre (talk) 21:27, 23 February 2020 (UTC)
replies: text:  then you're not converting to decimal, but to binary. That's very different — Do you mean the JavaScript snippet I pasted above? Because that's from my (unfinished) attempt at implementing the inverse of bytesToFloat32, which hasn't been pushed to GitHub yet. BTW, I should point out that these functions are purely an exercise to improve my own understanding of data formats – JavaScript already provides an interface for direct manipulation of a raw memory-buffer. --OmenBreeze (talk) 10:15, 24 February 2020 (UTC)
replies: text: With bytesToFloat32, you're converting a sequence of bytes representing a binary32 value to a binary32 value. There's no decimal here. And there's no decimal in the inverse of bytesToFloat32. The only things you have here are sequences of bytes and binary32 values (which are, as the name indicates, in binary). Vincent Lefèvre (talk) 12:05, 24 February 2020 (UTC)
replies: text:  No, because JavaScript represents numbers internally as 64-bit, double-precision floating-point values. Bitwise arithmetic is limited to 32-bit values only, and bitwise operations implicitly discard the decimal half of a  value. That's the extent to which JavaScript discriminates between fundamental number formats (sans the recently-added  primitive, which addressed the lack of arbitrary-precision arithmetic in JavaScript).In any case, you can see for yourself by copying the function body, removing the `export ` keyword, and pasting it into your browser's JavaScript console. Then run something like bytesToFloat32([0x41, 0xC8, 0x00, 0x00]);, taking into account that the result will resemble an integer () instead of a float (). --OmenBreeze (talk) 13:12, 24 February 2020 (UTC)
replies: text: Javascript numbers correspond to binary64 (note: this is binary, not decimal), but your function converts a binary32 encoding into a binary64 number, which is here also a binary32 number (binary32 is a subset of binary64). Anyway, this is an article about a floating-point format, not about Javascript specificities, and decimal is not involved here. Vincent Lefèvre (talk) 22:22, 24 February 2020 (UTC)
replies: text:  Yes, I'm aware that there's a precision loss; there's also a bytesToFloat64 function which performs the more accurate conversion. Both functions operate on numbers in the range of  (hence, "bytes") and encode a single- or double-precision value, respectively. Every value I've tested it with has yielded accurate results (see the repository's test suite). OmenBreeze (talk) 00:45, 25 February 2020 (UTC)
replies: text:  You're reading a binary32 number from its byte-encoding as a binary64 number. So, there is no precision loss. But I repeat that this has nothing to do with decimal as mentioned in the WP article, i.e. this is off-topic. Vincent Lefèvre (talk) 01:29, 25 February 2020 (UTC)
thread_title:  Ambiguous decimal-to-binary examples 

message: Is it ones complement, twos complement, or something else?  66.194.253.20 (talk) 13:01, 10 July 2020 (UTC)
replies: text: Negative numbers are represented by turning the sign bit on. The IEEE representation uses the sign-and-magnitude approach for storing the significand. InfoBroker2020 (talk) 10:16, 15 May 2021 (UTC)
thread_title:  Please describe how negative numbers are represented 

message: There have been some recent changes to the value of the largest representable number. These seem to have been undone. To discourage such changes, this post reports results of a simple test. Obviously, in the article proper, No Original Research.
In PostScript:
%!PS
/inf 2 2 -23 exp sub 2 127 exp mul def
(\ninf = ) =   inf =
() = () = () = () =
% Smallest x>0 such that x != 1+x
/tooBig 1e-07 def   /tooSmall 0 def   /guess -99 def
{
	tooBig tooSmall add 2 div  dup guess eq {pop exit} if
	/guess exch def
	guess 1 add 1 eq {/tooSmall} {guess = /tooBig} ifelse guess store
} loop  % Concludes that epsilon ~= 5.96047e-08 ~= 2^-24
(\nepsilon = ) =   tooBig =
/epsilonPlus1 tooBig 1 add def
() = () = () = () =
% 0 => largest possible float;
% 1 = boundary of what can be added to inf
% Multiplies by (1 + 2^-23)
[
	{3.40282e+38 {dup = epsilonPlus1 mul} loop}
	{1.01412e+31 {dup = inf 2 copy add eq = () = epsilonPlus1 mul} loop}
] 0 get exec  % Which test? Change integer.
Executed in Adobe Distiller Pro 11.0.23: 
Processing prologue.ps...
Done processing prologue.ps.
inf = 
3.40282e+38
7.5e-08
6.25e-08
6.09375e-08
6.01563e-08
5.97656e-08
5.9668e-08
5.96191e-08
5.96069e-08
5.96054e-08
5.9605e-08
5.96048e-08
5.96047e-08
5.96047e-08
5.96047e-08
5.96047e-08
5.96047e-08
epsilon = 
5.96047e-08
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
3.40282e+38
%%[ Error: undefinedresult; OffendingCommand: mul ]%%
Stack:
1.0
3.40282e+38
Observe that PostScript’s single-precision can cope with 3.40282×10³⁸, but that is the limit. JDAWiseman (talk) 17:22, 12 July 2021 (UTC)
thread_title:  3.4 × 10³⁸