Can I have range in switch case in C++?

Hello,
I have a float number and I want to use a switch case for this.

To solve float problem in the switch case, I multiply the number to 10.

But for range what I do?

For example:

17.5 ... 20 --> A
15 ... 17.5 ->B
12 ... 15 --> C
< 12 --> D



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;


#include <iostream>
using namespace std;


int main()
{
	float grade;
	cout << "Grade?? ";
	cin >> grade;

	switch ((int)grade*10)
	{
	case 175...200: //ERROR
		cout << "A";
		break;
	case 15...175: //ERROR
		cout << "B";
		break;
	default:
		cout << "D";
		break;
	}
}

You can't use a range (in c++).

If they had been equal intervals you might have been able to linearly transform, together with truncation, to get a single integer for each mark range.

You could use if ... else if, or you could put the grade boundaries in a parallel array and scan the array to find which was the last one that you exceeded.

BTW, floats aren't stored to perfect accuracy, so multiplying by 10 may not always be the panacea that you think.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
switch ((int) grade)
{
    case 200:
    case 199:
    case 198:
     ...

      "A" ...
   ...
    default "D"
}


that obviously has both flaws and kinda stinks, and even doing it without the *10 (its only a few entries per value that way) you still have some floating point issues. You may want to take a floor or ceil or round of the thing instead of just (int) casting.

if/then chain is easier to construct for this task.

you could spend some time to make an equation or something that gave the correct grade from a lookup table. This is how I would do it if I cared about performance or wanted to annoy whoever had to read and maintain it.

(grade >= 12) *( 1+ (int)(grade>=15) + (int)(grade>=17.5) );
if that is < 12 you get zero.
if its less than 15 and greater than 12 you get 1
if its greater than 15 and less than 17.5 you get 2
if its greater than 17.5 you get 3.
if you had a table "DCBA" table[0] is D, table[1] is C.... right?

... and I think i overengineered the expression. I think you can just sum the 3 terms and remove the 1. I was originally thinking the default to zero needed that multiply, until after I wrote it and looked at it.
so
(grade >= 12) + (int)(grade>=15) + (int)(grade>=17.5) ;
0,1,2,3 as before, just less weird :P

if not already obvious, you end up with a one-liner
result = table[expression];
Last edited on
lastchance wrote:
BTW, floats aren't stored to perfect accuracy, so multiplying by 10 may not always be the panacea that you think.

Do you mean if a number is let’s say 12.3999999999... it could become 12.4?
I’ve always supposed the floating point accuracy error would happen in some ‘negligible’ tiny digit — I’ve never taken into consideration the possibility that the error could propagate up to the first or second decimal digit…
@Enoizat,

Take a float (typical 6-7 digit accuracy)
11.99999
Add something with a "negligible tiny digit", say 0.00002, taking it to
12.00001

Now truncate both those numbers to integers ...
@lastchance,
actually, after having posted it, I realized it was a very silly concern. A written number is just a human readable representation of an abstract concept and the fact that two numbers have many different digits tells nothing about how much they differ.
The distance between 999998 and 999999 is the same as 999999 and 1000000, even if the latter look so different.
Thank you for you kind answer, anyway.
Topic archived. No new replies allowed.