Switch (expression) does not work with Float types

  • Thread starter Thread starter Sivas
  • Start date Start date
S

Sivas

Hi,

Can anyone tell me why this does not work:

---------------------------------------------

float b = 2.51F;

switch(b)
{
case 2.51F:
Console.WriteLine("A");
break;
default:
break;
}

Error: A value of an integral type expected

---------------------------------------------

It fails on the switch statement and does not go any further.

Any help is much appriciated.

Thanks,
Sivas
 
Can anyone tell me why this does not work:
---------------------------------------------

float b = 2.51F;

switch(b)
{
case 2.51F:
Console.WriteLine("A");
break;
default:
break;
}

Error: A value of an integral type expected

Because floating points tend do be less accurate than integers and might
shift a little dependin on the used processor it runs on and the generated
assembler code. floats are not a accurate number.

In theory you assign 2.51000000..... and compare with 2.51000000.....
according to your example, but in reality the internal saved registery
number might be ranging between 2.50999998..... 2.51000011..... depending on
the generated code of the compiler.

A tip: if you compare floats or doubles, always compare if the value is
between 2 minimum and maximum ranges (error).
This is why accounting software tend to store nubers with digits als integer
by multiplying by 100 and later get it back by dividing by 100.

I hope this helps?
 
Hi,

Can anyone tell me why this does not work:

---------------------------------------------

float b = 2.51F;

switch(b)
{
case 2.51F:
Console.WriteLine("A");
break;
default:
break;
}

Error: A value of an integral type expected

You can't use floats in a switch
integers and string only.

This is because
2.51F may not equal 2.51F at any given time
one of them may be 2.51000000000001

If you want this then you need to decide on the level of precision you
want and treat it as an integer

something like this should work
switch( (int)(b*100) )
{
case 251:
}

Vin
 
Sivas said:
Can anyone tell me why this does not work:

---------------------------------------------

float b = 2.51F;

switch(b)
{
case 2.51F:
Console.WriteLine("A");
break;
default:
break;
}

Error: A value of an integral type expected

From the ECMA spec, section 15.7.2:

<quote>
The governing type of a switch statement is established by the switch
expression. If the type of the switch expression is sbyte, byte, short,
ushort, int, uint, long, ulong, char, string, or an enum-type, then
that is the governing type of the switch statement. Otherwise, exactly
one user-defined implicit conversion (§13.4) must exist from the type
of the switch expression to one of the following possible governing
types: sbyte, byte, short, ushort, int, uint, long, ulong, char,
string. If no such implicit conversion exists, or if more than one such
implicit conversion exists, a compile-time error occurs.
</quote>

Using floating point numbers in a switch statement would just be asking
for trouble, even if you could do it, due to the nature of floating
point and the dangers of equality comparisons.
 
Sivas,

I would think that it has to do with the fact that the float type can
not represent exact values (which is really what you need for a switch
statement). I mean, how would you handle it? Would any value that differs
by Epsilon be allowed? It's not the kind of guesswork that the language
designers or a developer should have to deal with.

If anything, if statements are better for this, since I think you
probably have some specific logic that you have to handle.

Hope this helps.
 
Hi,

Thank you all for your expert answers. I stand before you all, much
the wiser!

Since I do have to use a 2 decimal precision number, I will go with
the suggested work around and multiply by a hundred. Thats slick,
actually!

Thanks heaps,
Sivas
 
Be careful, young wizard :-)

2.51 * 100 converted to integer may end up being 250, because the product
was 250.99999999 rather than 251.

All the Best
Julian N.
 
Julian said:
2.51 * 100 converted to integer may end up being 250, because the product
was 250.99999999 rather than 251.

Just add 0.5 to the product before explicit conversion and you get
mathematically correct rounding.

Christian
 
Or, just use the Decimal type. It will prevent the need for hacks such
as adding .5. Just declare the 2.50 as a decimal, perform the
multiplication, and then cast to an integer.
 
Back
Top