473,320 Members | 1,978 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

bits for floating value and converting

Hi,

I saw a line of codes in the "Fast Inverse Square Root" like this:

Float InvSqrt(float x)
{
.......
int i = *(int *) &x; //get bits for floating value
.....
x = * (float *) &i; //convert bit back to float
If x =1, &x = 0x0013fe54 and *(int *) &x = 1065353216. Can anyone
help me why I got these numbers? If I want to do the same operation in
Fortran, how can I do it?
Thanks a lot.

Haven
Nov 27 '07 #1
8 3138
my************@gmail.com wrote:
>
I saw a line of codes in the "Fast Inverse Square Root" like this:

Float InvSqrt(float x) {
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float

If x =1, &x = 0x0013fe54 and *(int *) &x = 1065353216. Can anyone
help me why I got these numbers? If I want to do the same operation
in Fortran, how can I do it?
The code is illegal, or at least system dependent. Conversion of
float* to int and of int to float* is undefined in C.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com

Nov 28 '07 #2
CBFalconer <cb********@yahoo.comwrites:
my************@gmail.com wrote:
>>
I saw a line of codes in the "Fast Inverse Square Root" like this:

Float InvSqrt(float x) {
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float

If x =1, &x = 0x0013fe54 and *(int *) &x = 1065353216. Can anyone
help me why I got these numbers? If I want to do the same operation
in Fortran, how can I do it?

The code is illegal, or at least system dependent. Conversion of
float* to int and of int to float* is undefined in C.
I suggest being careful with the word "illegal". I don't think the C
standard uses that term.

The quoted code does not violate any syntax rule or constraint, so in
that sense it's legal; an implementation is not required to reject it,
or even to issue any kind of diagnostic.

Conversion between int* and float* isn't undefined, but it can result
in Bad Things Happening. Specifically (C99 6.3.2.3p7):

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the
behavior is undefined. Otherwise, when converted back again,
the result shall compare equal to the original pointer. When a
pointer to an object is converted to a pointer to a character
type, the result points to the lowest addressed byte of the
object. Successive increments of the result, up to the size of
the object, yield pointers to the remaining bytes of the object.

So the above can certainly cause problems if int and float have
different alignment requirements, but it *can* work as expected on
some systems. But it's highly non-portable.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 28 '07 #3
my************@gmail.com wrote:
Float InvSqrt(float x)
{
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float
[ ... ] If I want to do the same operation in
Fortran, how can I do it?
Fortran has a "transfer" statement for this kind
of type punning. It's going to be machine-dependent
in Fortran just as in C.
--
pa at panix dot com
Nov 28 '07 #4
Hi, Walter Roberson:

Thank you for your quick reply and details. The whole source codes of
the fast square root algorithm are:

float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases
accuracy
return x;
}

Based on your explanation, *(int*)&x will get the "IEEE 754 single
precision floating point Representation" of x, and *(float*)&i will
convert that representation back to a floating number?

Also, what is the algorithm to covert between "IEEE 754 single
precision floating point Representation" and normal floating number?

Thanks a lot.

Sincerely yours,

Haven
Nov 28 '07 #5
On Nov 27, 7:25 pm, Keith Thompson <ks...@mib.orgwrote:
CBFalconer <cbfalco...@yahoo.comwrites:
myfem.analy...@gmail.com wrote:
I saw a line of codes in the "Fast Inverse Square Root" like this:
Float InvSqrt(float x) {
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float
If x =1, &x = 0x0013fe54 and *(int *) &x = 1065353216. Can anyone
help me why I got these numbers? If I want to do the same operation
in Fortran, how can I do it?
The code is illegal, or at least system dependent. Conversion of
float* to int and of int to float* is undefined in C.

I suggest being careful with the word "illegal". I don't think the C
standard uses that term.

The quoted code does not violate any syntax rule or constraint, so in
that sense it's legal; an implementation is not required to reject it,
or even to issue any kind of diagnostic.

Conversion between int* and float* isn't undefined, but it can result
in Bad Things Happening. Specifically (C99 6.3.2.3p7):

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the
behavior is undefined. Otherwise, when converted back again,
the result shall compare equal to the original pointer. When a
pointer to an object is converted to a pointer to a character
type, the result points to the lowest addressed byte of the
object. Successive increments of the result, up to the size of
the object, yield pointers to the remaining bytes of the object.

So the above can certainly cause problems if int and float have
different alignment requirements, but it *can* work as expected on
some systems. But it's highly non-portable.
It violates aliasing rules, and not just in theory:

muntyan@munt10:/tmp$ cat file.c
#include <stdio.h>

int main (void)
{
float a = 2.;
int b = *(int*)&a;
b = ~b;
a = *(float*)&b;
printf ("%f\n", a);
return 0;
}
muntyan@munt10:/tmp$ gcc file.c # no optimizations
muntyan@munt10:/tmp$ ./a.out
-2.000000
muntyan@munt10:/tmp$ gcc file.c -O2
muntyan@munt10:/tmp$ ./a.out
0.000000

Best regards,
Yevgen
Nov 28 '07 #6
On Nov 27, 10:03 pm, myfem.analy...@gmail.com wrote:
Hi, Walter Roberson:

Thank you for your quick reply and details. The whole source codes of
the fast square root algorithm are:

float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases
accuracy
return x;

}
It's broken, you need to do something like

float InvSqrt(float x)
{
union {
float f;
int i;
} u = {x};
float xhalf = 0.5f*u.f;
u.i = 0x5f3759df - (u.i>>1);
u.f = u.f*(1.5f-xhalf*u.f*u.f);
return u.f;
}

It is broken too, but at least it's guaranteed to work with gcc, for
what it's worth.
Based on your explanation, *(int*)&x will get the "IEEE 754 single
precision floating point Representation" of x, and *(float*)&i will
convert that representation back to a floating number?

Also, what is the algorithm to covert between "IEEE 754 single
precision floating point Representation" and normal floating number?
No idea about IEEE 754 part.

Best regards,
Yevgen
Nov 28 '07 #7
On Wed, 28 Nov 2007 02:26:54 +0000 (UTC), pa@see.signature.invalid
(Pierre Asselin) wrote:
my************@gmail.com wrote:
Float InvSqrt(float x)
{
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float

[ ... ] If I want to do the same operation in
Fortran, how can I do it?

Fortran has a "transfer" statement for this kind
of type punning. It's going to be machine-dependent
in Fortran just as in C.
TRANSFER intrinsic _function_; since F90 (if that matters).
Or, since forever, the EQUIVALENCE statement (declaration).

Fortran (including FORTRAN) does require single-precision float,
called REAL, and 'default-kind' INTEGER, to be the same size,
the equivalent of which C does not, as already noted elsethread.
But like C it does not require any particular representation of
floats, and actually less than C for integers.

But as already noted, the place to ask about the Fortran part is
comp.lang.fortran . The what-does-the-C-do part is (was) ontopic here,
but in practice would also be accepted in c.l.f even though it's not
Fortran; first they have much lower volume and can thus afford to be
less strict about topicality; and second most Fortran implementations
have specific features for C interoperability (though not standardized
until recently) whereas most C implementations don't do anything for
interoperability with other languages.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Dec 10 '07 #8
my************@gmail.com wrote:
Hi,

I saw a line of codes in the "Fast Inverse Square Root" like this:

Float InvSqrt(float x)
{
......
int i = *(int *) &x; //get bits for floating value
....
x = * (float *) &i; //convert bit back to float
If x =1, &x = 0x0013fe54 and *(int *) &x = 1065353216. Can anyone
help me why I got these numbers? If I want to do the same operation in
Fortran, how can I do it?
Presumably, this was meant to be K&R (pre-89 standard) C. Not that many
C programmers caught up for the first decade. If you used unions to
represent data which could be interpreted in either int or float
representation, the analogy to Fortran EQUIVALENCE might be clearer.
Since 1990, TRANSFER is the recommended (and less arcane) Fortran syntax
for copying a bit pattern between data types.
Most common CPU architectures include a fast approximate inverse square
root instruction. It is not accessed by type punning or similar tricks,
which defeat the description "fast" by requiring moves between data
types which aren't supported efficiently. The need for it is greatly
reduced in CPUs introduced this year (all brands of which I know) which
support more efficient sqrt() without approximations.
So, it appears the code of which you speak is of mainly historic
interest, and may not even work the same on any post-1990 CPU as it may
have done when it was written.
Dec 10 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Ben | last post by:
Hi, I need to write some data types into an array of unsigned chars. These are basically "signals" within a message, so each signal will have a start bit and a length. The signals will also...
8
by: Rick | last post by:
Hi, Does C have some handy functions to convert chars, ints and floats to bit arrays? I need to store that stuff binary so a few functions would be great. Converting chars and ints isn't...
53
by: Zhiqiang Ye | last post by:
Hi, All I am reading FAQ of this group. I have a question about this: http://www.eskimo.com/~scs/C-faq/q7.31.html It says: " p = malloc(m * n); memset(p, 0, m * n); The zero fill is...
64
by: yossi.kreinin | last post by:
Hi! There is a system where 0x0 is a valid address, but 0xffffffff isn't. How can null pointers be treated by a compiler (besides the typical "solution" of still using 0x0 for "null")? -...
4
by: rz0 | last post by:
Hi all, This is a question about both C89 and C99 and is based on my partial reading of the standard drafts (one from before C89 but mainly N1124). If appropriate, please give a...
11
by: rajm2019 | last post by:
count the bits required to be altered while swaping values a and b
29
by: Virtual_X | last post by:
As in IEEE754 double consist of sign bit 11 bits for exponent 52 bits for fraction i write this code to print double parts as it explained in ieee754 i want to know if the code contain any...
15
by: arnuld | last post by:
Next month I will start to work on a C++ based Software named CAT++ which is going to provide FORTRAN like arrays in C++ and will be used within Scientific Community and hence will heavily depend...
8
by: Hahnemann | last post by:
Is there a sample in C out there to represent a sequence of numbers (shorts) using bits? With the intention of saving space, instead of using the full 16 bits per short. Thanks. - Hahnemann
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.