Thread: long int issue

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    38

    long int issue

    when i have
    this:

    Code:
    int row=100000;
    int col = 100000;
    int prec =1;
    long selection = ((row * col) * prec)/100;
    selection end up being:
    14100654.

    i should be getting 100000000;

  2. #2
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428
    My guess is when you multiply 100000 * 100000 * 1 the result is past the limit of a long. So it screws up the number when it passes the roof then divides that screwed up number by 100. If you drop a 0 of the end of row and column you notice it will display the appropriate result.

    climits (limits.h) - C++ Reference

    the limit listed of a long is
    2147483647
    the result of 100000 * 100000
    10000000000

    I don't know for sure that this is causing the problem but it would be my first guess.

  3. #3
    Novice
    Join Date
    Jul 2009
    Posts
    568
    What he said.

    You can explore various datatype limits like so:
    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main(void)
    {
        // Replace long as you please.
        cout << "Upper limit of long datatype: " << numeric_limits<long>::max() << endl;
        cout << "Lower limit of long datatype: " << numeric_limits<long>::min() << endl;
    
    }
    Last edited by msh; 09-11-2010 at 02:51 AM. Reason: Redundant.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    In the code provided in the original post, row and col are int. so row*col is computed as an int. If an int has smaller range than a long, that will also overflow.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    30
    "long selection = ((row * col) * prec)/100;"
    Even if your compiler's "long" is 64bit, and can store 10^10, this will not work, because all of the operands are int, the result will be truncated to int.
    You need to cast one of "row" or "col" to "long" first, for example
    "long selection = ((long)row)*col*prec/100;"

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    ((row * col) * prec)/100l might work as well.
    (Notice the trailing l.)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    ((row * col) * prec)/100l might work as well.
    (Notice the trailing l.)
    No it wouldn't. row*col will be computed as an int, as will ((row*col)*prec). The result would then be promoted to long, in order to divide by 100L.

    Incidentally, from a readability perspective, I personally prefer 100L over 100l. I realise others may have different preferences, but lower case L looks too much like the bitwise "or" operator (or like the digit 1) on a lot of screens.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    log2(100000 * 100000) is about 33.2 which means that the intermediate value would exceed a 32bit limit. You're also doing division so I wonder if floating point numbers would be more appropriate for your needs? Or else you could use 64bit integer values:
    Code:
    int row = 100000;
    int col = 100000;
    int prec = 1;
    long long selection = (((static_cast<long long>(row) * col)) * prec) / 100;
    Notice that row is upcast to a 64bit integer so that the intermediate result doesn't get truncated.

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Sometimes it is confusing on where to cast or specify the trailing L or d. But I think the rule is that

    type1 operator type2 -> type3, where type3 the biggest in size of type1, type2.
    if there are integral vs decimal types, the integral are casted to decimals.

    I am not sure if float * int would result in float or to double, but I would think to float.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But I think the rule is that

    type1 operator type2 -> type3, where type3 the biggest in size of type1, type2.
    if there are integral vs decimal types, the integral are casted to decimals.
    That is a rough summary, but the actual rules are:
    Quote Originally Posted by C++03 Section 5 Paragraph 9
    Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:
    • If either operand is of type long double, the other shall be converted to long double.
    • Otherwise, if either operand is double, the other shall be converted to double.
    • Otherwise, if either operand is float, the other shall be converted to float.
    • Otherwise, the integral promotions shall be performed on both operands.
    • Then, if either operand is unsigned long the other shall be converted to unsigned long.
    • Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.
    • Otherwise, if either operand is long, the other shall be converted to long.
    • Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

    [Note: otherwise, the only remaining case is that both operands are int ]
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Debug Error Really Quick Question
    By GCNDoug in forum C Programming
    Replies: 1
    Last Post: 04-23-2007, 12:05 PM
  2. Converted from Dev-C++ 4 to Dev-C++ 5
    By Wraithan in forum C++ Programming
    Replies: 8
    Last Post: 12-03-2005, 07:45 AM
  3. Switch/case Problems (long code in post)
    By Wraithan in forum C++ Programming
    Replies: 2
    Last Post: 12-01-2005, 06:40 PM
  4. HUGE fps jump
    By DavidP in forum Game Programming
    Replies: 23
    Last Post: 07-01-2004, 10:36 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM