7

I'm confused!

Today is November 3rd

DateTime DateTime = new DateTime(2010,11,3);
long shazbot = 1000000000 * DateTime.Day;

shazbot comes out to -1294967296

Huh???

Community
  • 1
  • 1
sooprise
  • 22,657
  • 67
  • 188
  • 276
  • I have never used C# but it looks like your long is 32 bits. Signed. huh. – Josh Davis Nov 03 '10 at 14:14
  • @Josh, in C# `longs` are [64-bit](http://msdn.microsoft.com/en-us/library/ctetwysk%28VS.71%29.aspx) wide. – Frédéric Hamidi Nov 03 '10 at 14:15
  • Try to multiply other pair of System::Int32 and System::Int64 . I'm not C# dev, just interested. – foret Nov 03 '10 at 14:15
  • @foret: Multiplying two different numeric types will cause an [implicit conversion](http://msdn.microsoft.com/en-us/library/y5b434w4.aspx) for the smaller type to the larger. `System.Int32` * `System.Int64` gives you a `System.Int64` back. – Powerlord Nov 03 '10 at 14:25

2 Answers2

41

shazbot may be a long, but neither 1000000000 or DateTime.Day are. So, C# does int multiplication first (which results in an overflow) then casts it to a long to store in shazbot.

If you want a long result, make one of them a long, like this:

long shazbot = 1000000000L * DateTime.Day;

Edit: C# gives you a warning if you use l instead of L. Fixed.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • How do I convert my values to long? Convert.ToInt64? – sooprise Nov 03 '10 at 14:15
  • Alternatively, yes, use a cast like Alexander suggested. It's just easier if you're using literals to use the type suffix. – Powerlord Nov 03 '10 at 14:19
  • Good catch.. wonder in what framework .NET will do that by itself. :) – Shadow The GPT Wizard Nov 03 '10 at 14:19
  • 7
    @Soo, "l" is not a trick, it's what tells the compiler what the number is. Similar to "d" for double, "f" for float, "m" for decimal. Otherwise, if you provide an integer literal, the compiler will infer it as an integer, and all decimal literals will be inferred as double. Although if you are going to use the character, the suggestion is to use uppercase L since l is easily confused for 1. – Anthony Pegram Nov 03 '10 at 14:20
  • 2
    @RobertPitt: I noticed that... it's strange how the (relatively) simple answers tend to get tons of upvotes fairly quickly, but the ones I take a long time to research and write don't. :| – Powerlord Nov 03 '10 at 14:20
  • @Anthony: Actually, I noticed when I tried it (to make sure `l` really was `long`, I use Java more at work than C# now) that the VS C# compiler spits out a warning if you use `l`, so I updated the original post to use `L` and left an edit note about it. – Powerlord Nov 03 '10 at 14:23
  • @R. Bemrose. It's because everybody can spot a good answer right away when it's simple question :) so, we see the easy question, enter to answer it, see the earliest answer, and instead of writing the same answer again, we upvote. – Alex Nov 03 '10 at 14:25
  • @Alexander: There's just a certain form of irony that I'm a 20k+ user and this is now my second-highest voted answer. – Powerlord Nov 03 '10 at 16:05
  • By the way this is similar in Java. – Christophe Roussy Jul 07 '20 at 16:04
1

Cast to long like this:

long shazbot = 1000000000L * DateTime.Day;
Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
  • 1
    It's enough to cast one of them to `long` to get the expression to evaluate as long. – Øyvind Bråthen Nov 03 '10 at 14:21
  • Too much to write. There is absolutely no need to cast both operands. One is sufficient. The second will be implicitly cast into the right type. Or, like R. Bemrose suggested, to write a Long literal instead of the default int literal, so that no cast would be needed in this case. – Alex Nov 03 '10 at 14:23
  • Thanks I'll change my example. – Jeff LaFay Nov 03 '10 at 14:28