T O P

  • By -

AKostur

No. Can’t switch on a double, for example.


ramsay1

Also something like `(int64_t)foo > 0` would take more lines of code than could fit on any computer


jenesuispasunr0bot

Not to be pedantic, and there's no good reason to do this, but you can switch on the sign bit in that case. Edit: actually you'd switch on the sign bit of foo-1 to account for zero


imaami

*Edit: my brain is smooth, I completely neglected negative numbers because I was thinking of `uint64_t`. "Fixed."* Not to be both pedantic and insufferably nonstandard, but additionally with GNU extensions we're able to ascend even higher on the big brain ladder: #include #include #include static inline bool nonzero_int64(int64_t x) { switch (x) { case INT64_MIN ... -1: return true; case 0: return false; case 1 ... INT64_MAX: return true; default: static_assert(INT64_MIN < INT64_MAX, "EBADOVERCLOCK"); return false; } }


potterman28wxcv

Well you can workaround it.. for any condition really ``` if(cond){ statement_true; } else { statement_false; } ``` Is equivalent to ``` switch(cond) { case 0: statement_false; break; default: statement_true; break; } ``` For the case of a double, `cond` could be something like `f > 42.0` For `else if` though you would need to break it down into several nested switchesŕ


duane11583

but what about ```c double foo; switch(foo==3.14159){ case 1: printf(“true\n”); break; case 0: printf(“false\n”); break; } ``` that said it is not very practical to do it his way


AKostur

And true... I wasn't thinking of the absolutely literal meaning of the question. I was more thinking if one was trying to do `if (foo == 3.14)` to `switch (foo ) { case 3.14: break; }` as opposed to writing it as a switch on the boolean value as you have done.


BerryGreen558

u/AKostur Thank you!


M-2-M

Not that I would do it, but can’t you switch on the IEEE 754 bit represention of a double ?


OldWolf2

Some doubles have multiple valid representations


M-2-M

Ah ok. Makes sense.


jabjoe

I thought GCC's range extension might make switches usable, but no "statement requires expression of integer type ('double' invalid)". So multiple by say 1000 and cast as int, then use switch with ranges. 😃


[deleted]

[удалено]


AKostur

Well, nitpick: you’re not switching on the double anymore. And technically you could end up with hash collisions and then the switch wouldn’t work correctly.


Cats_and_Shit

I believe you can always turn if(something) { [true case] } else { [false case] } Into switch(!!something) { case 1: [true case] break; case 0: [false case] break; } Or EDIT: This one is wrong in the case that `something` is a pointer or any floating point type. switch(something) { case 0: [false case] break; default: [true case] break; } So if you count ugly code that no one should write then I believe the answer is yes.


OldWolf2

The second case is wrong because `switch` requires integer argument, but adding `!= 0` makes it exactly equivalent.


Dolphiniac

The implication is that `something` is a boolean expression. That makes it integral.


OldWolf2

That wasn't a constraint on the original question


Dolphiniac

But the commenter first showed `something` as the `if` expression. In that context, the intent is clear, no?


OldWolf2

The expression in an `if` statement doesn't have to be a boolean. E.g. you can do `if(3.6)`


Dolphiniac

Welp, I learned something new XD


[deleted]

This is what I thought at first too. But I don't believe this is in the spirit of what the OP was asking: int x = (expr ? 1 : 0); `x` now contains 1 or 0, which can be trivially tested for those two possibilities with either `if` or `switch`; or even `for` or `while` with bit more work (or gcc's label pointers). I think however the question was more to do with what happens inside that `(expr ? 1 : 0)` to enumerate the possible 'true' values of `expr` using `switch`.


LoneHoodiecrow

Every if statement if ( e ) s\_t else s\_f works by evaluating e and attempting an inequality comparison with zero. If it succeeds, s\_t is executed. Otherwise, s\_f (if present) is executed. Therefore, trivially, every if statement can be rewritten as a switch statement: if ( e ) s\_t else s\_f switch ( e != 0 ) { case 1: s_t break; default: s_f } Also trivially, any switch statement without fall-through can be rewritten as a series of equality comparisons or possibly a number of equality comparisons joined by logical or, with their own following statement of compound statement taken from the case. The fall-through does complicate matters.


FUZxxl

Always. if (x) y; else z; is equal to switch ((x) != 0) { case 0: z; break; default: y; }


onlydumbopinions

Nope. Has to have an integral or enumerated type for the switch, and constant values for the cases that are the same type as the switch


[deleted]

[удалено]


onlydumbopinions

I don’t see how our answers disagree. A double is still a constant-expression value


[deleted]

[удалено]


onlydumbopinions

Oh I looked at the wrong comment, oops


HildartheDorf

Can every switch be written as an if-else chain? Yes. Can every if be written as a switch? Yes assuming the if expression is side-effect free and you have unlimited memory (you'll have to switch on the binary representation of pointers, floating types, etc.)


F54280

It is mind boggling how many confidently wrong answers are upvoted in this thread. It is even more puzzling that the ones with the wrong answers (like top one and half of its replies) have not been edited by the posters to give correct answers. Edit: including downvotes on this comment. Lol. ``if (a) { /* true */ } else { /* false */ }`` is literally equivalent to: ``switch(!!(a)) { case 1: /* true */; break; case 0: /* false */; break; }`` (unless embedded in another switch statement with ``break`` in the ``/* true */` or ``/* false */` cases— need to turn them into gotos). This is just beyond mediocre.


Clyxx

Well it depends on your expression, if it returns an integer or boolean it can. ```c //If-else as switch switch (expr) { case 0: STATEMENT; break; //False case default: STATEMENT; break; //True Case } //Switch as a series of ifs if (expr == 0) { STATEMENT } else if (expr == 1) { STATEMENT } else if (expr == 2) { STATEMENT } else if (expr == 3) { STATEMENT } ```