0

This is probably a very easy answer, but I couldn't figure out what the problem is in this situation. I would like to convert a double to a short (and vice versa), but by doing so I get different results.

For example:

double test = 33768; test=33769
short valuetest = (short)test; valuetest = -31768

short test2 = -31768; test2 = -31768
double valuetest2 = (double) test2; valuetest2 = -31768

In my use case, valuetest2 should have the value 33768, or that's what I try to accomplish anyway. What's the better way to achieve this result? Or could someone explain why by casting the value of the first test changes from 33769 to -31768? Thanks in advance!

CaptHook2K
  • 13
  • 1
  • 4
    Signed shorts can store values from -32768 to +32767. – Rup Jun 24 '20 at 15:15
  • The pigeonhole principle should tell you that it's not possible for every unique value representable by a 64-bit double to map to a unique 16-bit short, let alone roundtrip back to the original value. – Ben Voigt Jun 24 '20 at 15:20
  • This is documented in [Explicit Numeric Conversions](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#explicit-numeric-conversions): *When you convert a double or float value to an integral type, this value is rounded towards zero to the nearest integral value. If the resulting integral value is outside the range of the destination type, the result depends on the overflow checking context. In a checked context, an OverflowException is thrown, while in an unchecked context, **the result is an unspecified value of the destination type**.* – dbc Jun 24 '20 at 15:52
  • To avoid this sort of confusion, you can use `checked` as shown in the accepted answer to [Best (safest) way to convert from double to int](https://stackoverflow.com/q/3549179/3744182) -- the same answer applies to conversions to `short` and `int`. In fact I think this may be a duplicate, agree? [Why casting big double value in sbyte returns 0 in C#?](https://stackoverflow.com/q/59755716/3744182) and [Weird result from unchecked(), possible compiler bug?](https://stackoverflow.com/a/6883965/3744182) might also apply. – dbc Jun 24 '20 at 16:05

1 Answers1

0

This Microsoft article may help you. Your value is outside the range of short values, so it becomes a negative value. This is because of how negative numbers are usually represented in binary, known as two's complement. See this Wiki article for more information on two's complement.

In short, consider the value 32768, which is one more than the max value for a short. In this case, the leading digit in binary becomes a one, which changes the sign and makes the value the minimum value for a short.

Going further, 32769 as a short should have the value -32767, 32770 would be -32766, and so on.

siralexsir88
  • 418
  • 1
  • 4
  • 14