0

What do I overlook in the expression below? Does not Int64 type has larger range than Int16?

Int64 value = (Int64)(System.Data.SqlTypes.SqlInt16.MaxValue+1);

System.Data.SqlTypes.SqlInt16.MaxValue is 32767. Int64.MaxValue() is 9223372036854775807.

32767 + 1 = 32768. And that is much(!) lower than 9223372036854775807.

So why do I get Aritmethic Overflow when I cast

(Int64)(System.Data.SqlTypes.SqlInt16.MaxValue+1);

to Int64?

(Is it something to do with the implementation of + operator in C# or...?)

0

5 Answers 5

3

SqlTypes.SqlInt16 is an interesting type. It looks like a short? but it is not, it is actually a struct. It has a bunch of operator overloads that makes it behave like a number. Do note how this version works just fine:

    Int64 value = (Int64)(short.MaxValue + 1);    // okay

Which uses the "normal" addition operator, it can never overflow since the CLR doesn't actually have a addition operator that works for short. The nearest type it supports is Int32, that doesn't overflow here.

But SqlInt16 was written to catch this mistake, it has an operator+() overload, it was explicitly written to generate this exception. In other words, it does implement the semantics of a 16-bit addition and yells when the result doesn't fit back into a dbase table column of a 16-bit integral type. Regardless whether you use the checked or unchecked keywords in C#. Which is a Good Thing, you really want to know about that when you work with a dbase.

You need to invoke another method of SqlInt16, a conversion operator. The one that converts SqlInt16 to a native integral type. The tongue-in-cheek variety looks like this:

   Int64 value = (Int64)((short)System.Data.SqlTypes.SqlInt16.MaxValue + 1);

But of course it makes more sense to cast to Int64 directly, SqlInt16 has a conversion operator for that one too:

   Int64 value = (Int64)System.Data.SqlTypes.SqlInt16.MaxValue + 1;

Do beware the iffy semantics of code like this. You can't cast a dbase column. My first snippet makes more sense.

Sign up to request clarification or add additional context in comments.

Comments

2

You are trying to cast the result ot SqlInt16.MaxValue+1 to an Int64. But SqlInt16.MaxValue is a SqlInt16. Adding +1 to that will overflow before you even cast it.


What you want to do is first cast the SqlInt16.MaxValue to Int64 and then add 1 to it:

Int64 value = (Int64)System.Data.SqlTypes.SqlInt16.MaxValue + 1;

Comments

1

Do this instead, you're trying to add 1 to the max value of System.Data.SqlTypes.SqlInt16

Int64 value = (Int64)(System.Data.SqlTypes.SqlInt16.MaxValue) +1;

Comments

1

Because (System.Data.SqlTypes.SqlInt16.MaxValue+1) is an int16 - or trying to be at least, which is invalid.

Just cast the MaxValue to int64 first, then add 1 afterwards.

Just to examplify this:

var x = (System.Data.SqlTypes.SqlInt16.MaxValue + 0);
var t = x.GetType(); // t will be System.Data.SqlTypes.SqlInt16

Comments

0

Hover your mouse over the + sign in your code, and you will get a tool tip popping up telling you it (overload resolution) goes to a "user-defined" operator. Choose "Go to definition" or F12 on that + character, and you will see the signature:

public static SqlInt16 operator +(SqlInt16 x, SqlInt16 y);

(documentation)

So you now know that the right-hand operand 1 is implicitly converted to SqlInt16 (first converted implicitly from int to short via C#'s rules for constant (literal) expression conversions, then converted from short to SqlInt16 via a "user-defined" implicit operator). Then we have two SqlInt16 values. The operator above takes them in and wants to return a third SqlInt16 value, their sum. But that is impossible. The exception arises.

So we never get to your cast to Int64; the problem occurs before that.

To fix it, explicitly convert System.Data.SqlTypes.SqlInt16.MaxValue to e.g. Int64 (a.k.a. long) or Int16 (a.k.a. short) before the addition (+).

Of course, you can also use:

long value = short.MaxValue + 1;

because short.MaxValue has the same numerical value as SqlInt16.MaxValue, but I don't know if you can use this in your application.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.