A program that spells a float number

Can someone help me with a program in c++ that spells a float number
What do you mean by "spells"? If you want to display a float you can do this:
1
2
3
4
5
6
int main()
{
    float a = 3.14159f;
    std::cout << a;
    return 0;
}


If you are trying to display the individual bits, you can do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>

union ufloat 
{
    float f;
    unsigned long u;
};

int main()
{
    ufloat a;
    a.f = 3.14159f;
    std::cout << std::setw(8) << std::setfill('0') << std::hex 
              << a.u;
    return 0;
}
40490fd0


For a double do this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>

union udoub
{
    double d;
    unsigned long long u;
};

int main()
{
    udoub a;
    a.d = 3.14159;
    std::cout << std::setw(16) << std::setfill('0') << std::hex 
              << a.u;
    return 0;
}
400921f9f01b866e
Last edited on
That one work also:

#include <iostream>
#include <bitset>

int main()
{
	union
	{
		float a;
		unsigned int b;
	} myfloat;
	
	myfloat.a = 1.23456789;
	
	std::bitset<32> showfloat(myfloat.b);
	std::cout << showfloat << std::endl;

	return 0;
}
Last edited on
Every bit of code with the word union in it in this thread results in undefined behavior.
> a program in c++ that spells a float number

To just spell out the digits, something like this would do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::string spell( double number )
{
    std::ostringstream stm ;
    stm << std::fixed << number ;
    std::string number_string = stm.str() ;

    // trim traling zeroes
    auto pos = std::max( number_string.find('.'), number_string.find_last_not_of('0') ) ;
    number_string.erase( number_string.begin() + pos + 1, number_string.end() ) ;

    std::string result ;
    static const char* const numbers[] = { "zero ", "one ", "two ", "three ", "four ",
                                           "five ", "six ", "seven ", "eight ", "nine " } ;
    for( char c : number_string ) result += ( c == '.' ) ? "point " : numbers[ c - '0' ] ;
    return result ;
}


For something more elaborate, see http://rosettacode.org/wiki/Number_names#C.2B.2B
Oh! As in number-to-string! That is completely different from what I understood.
Every bit of code with the word union in it in this thread results in undefined behavior. 


Because it depends on the machine the code is running on.
Because it depends on the machine the code is running on.


Because the standard says it's undefined.
Please be a bit more precise about the context with unions and undefined. Maybe a citation would help.
I figured that you might tell the page or give an explanation. I cannot find any conherence to this case and being undefined. The standard doesn't say anything about undefined usage of an union with non-static data members. It says the size will depend on the largest member and in our case that depends on the machine. That means the union is declared, defined but not yet initialized. But a non-static data member of a union may have an equal-initializer. Thats what we have here. So everything is just fine but you need to take care of what happens.
9.5.1 of draft n3337
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time. [ Note: One special guarantee
is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout
structs that share a common initial sequence (9.2), and if an object of this standard-layout union type
contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2. —end note ] The size of a union is sufficient to contain the largest
of its non-static data members. Each non-static data member is allocated as if it were the sole member of a
struct


Note, specifically: The value of at most one of the non-static members may be active at any one time.

For:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
	union
	{
		float a;
		unsigned int b;
	} myfloat;
	
	myfloat.a = 1.23456789;
	
	std::bitset<32> showfloat(myfloat.b);
	std::cout << showfloat << std::endl;

	return 0;
}


the active member is myfloat.a on line 9 when you write to it.

On line 11 you venture into undefined territory by accessing the inactive member, b. Does it do something sensible? One would have to question the QOI of compilers that didn't. Is it undefined behavior? Yes.

See also:
http://stackoverflow.com/questions/2310483/purpose-of-unions-in-c-and-c
Last edited on
The programmer needs to keep track of the union.

#include <iostream>
#include <bitset>

int main()
{
	struct transpose
	{
		char used;
		union
		{
			float a;
			unsigned int b;
		};
	} myfloat;
	
	myfloat.a = 1.23456789;
	myfloat.used = 0;
		
	myfloat.used = 1;
	if(1 == myfloat.used)
	{
		std::bitset<sizeof(float)*8> showfloat(myfloat.b);
		std::cout << showfloat << std::endl;
	}
	
	return 0;
}
Last edited on
used doesn't have anything to do with which member is active, unless, as you say the programmer uses it to keep track of which is active. Changing it, however, doesn't change which member is active.

This is still undefined behavior.
Last edited on
Would you please give an explanation how to use an union correctly.
Topic archived. No new replies allowed.