5

Can someone please explain how float to uint32_t casting works? Is it a valid conversion?

The output of the first line in the below code make sense to me, but the rest are I can't figure out myself.

cout<<uint8_t(256+33)<<'\n';
cout<<uint8_t(float(256+33))<<'\n';
cout<<int(uint8_t(float(256+33)))<<'\n';
cout<<int(uint8_t(float(256+3)))<<'\n';
cout<<int(uint8_t(float(256+20)))<<'\n';

output

!
�
255
255
255

uint8_t(256+33) is int to unsigned char, and it gives !, which is what I expect. However, float to uint8_t does not work at all. And when I try to cast the output to int, it gives me constant number 255.

I've a vector<float> and want to convert it into vector<uint8_t>, which will to passed into a function. What it a valid way to convert float to uint8_t? Will static_cast<uint8_t> will work? Should I first convert float to int and then int to uint8_t?

Anonymous
  • 255
  • 1
  • 10

1 Answers1

5

They are not valid, but are undefined.

In C++17:

4.10 Floating-integral conversions [conv.fpint]

A prvalue of a floating-point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type.

The int conversion is well-defined, which you can't assume just because the result makes sense to you:

4.8 Integral conversions [conv.integral], item 2

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type).

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • 1
    To complete: the first one instead is well defined because a conversion from a signed integral type to an unsigned one is specified to work modulo 2^n_bits – Matteo Italia Oct 26 '22 at 11:45