Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

C 

C - when to use (long long) before the operation?

So my question is, how do i know when do i have to use (long long), or (long) or any other data type before the operation... I don't understand what's the point and when to use it.

In the example below, without (long long) the result ended up somehow being negative and incorrect.

Code
unsigned long long myNumber;

(loop)
myNumber+= (long long) pow(2, i);
(endofloop)
It is a question of the size of datatype.
Unsigned long long can hold value from 0 - 18446744073709551615.
Unsigned long can hold value from: 0 - 4294967295

https://en.wikipedia.org/wiki/C_data_types
[Image: 4bj39qK.png]
(Sep 6, 2017 08:55 AM)Trip2nite Wrote:  It is a question of the size of datatype.
Unsigned long long can hold value from 0 - 18446744073709551615.
Unsigned long can hold value from: 0 - 4294967295

https://en.wikipedia.org/wiki/C_data_types

yeah i know that, but the question is why do i need to put (long long) before pow(2, i)

myNumber is already unsigned long long, why is needed then
myNumber+= (long long) pow(2,i);
(Sep 6, 2017 09:44 AM)FaberCastell Wrote:  yeah i know that, but the question is why do i need to put (long long) before pow(2, i)

myNumber is already unsigned long long, why is needed then
myNumber+= (long long) pow(2,i);
Well, IIRC pow (in math.h) returns a double.
You are essentially just casting it from double to long long.
[Image: 4bj39qK.png]
(Sep 6, 2017 10:17 AM)Trip2nite Wrote:  Well, IIRC pow (in math.h) returns a double.
You are essentially just casting it from double to long long.

His variable is unsigned long long and he used long long for casting. There was no C89 support for long long but MSVC supports it.
https://hackforums.net/showthread.php?tid=6333106

Cheap Telegram RAT written in Rust
The answer can probably be easily found if you look into IEEE754, two's compliment (signed vs unsigned).. But even then I'm still unsure on how or WHY you think the result would be negative when your storage type is unsigned. Perhaps you were calling printf() with a "signed" specifier like %d incorrectly, when it should have been %u with the proper length (%llu)?
Getting Started: C/C++
[C/C++/.NET/x86 ASM - Automation Programmer]
(Sep 6, 2017 12:10 PM)0xDEAD10CC Wrote:  The answer can probably be easily found if you look into IEEE754, two's compliment (signed vs unsigned).. But even then I'm still unsure on how or WHY you think the result would be negative when your storage type is unsigned. Perhaps you were calling printf() with a "signed" specifier like %d incorrectly, when it should have been %u with the proper length (%llu)?

Could be that. My point though was when do i have to use (long long) and someone mentioned that pow returns a double so that's what i wanted. Do all operations from math.h return a double or how do i know when do i have to cast another data type?
I don't understand your question, have you read the responses? Different datatypes have different limits and precision. You determine what you need based on what you're doing and the types returned by functions, simple.
Getting Started: C/C++
[C/C++/.NET/x86 ASM - Automation Programmer]
Yes but i set datatype unsigned long long myNumber

but why do i have to do then myNumber+=(long long) pow(2,i)

I have already assigned "unsigned long long" to myNumber - then why do i have to do (long long) before pow.

I don't understand when i have to do this (long long) again when my integer is already unsigned long long - how can you determine if you have to or not?
Why do you think you need to? I already told you - you're not going to get a negative result from an unsigned type. When you cast things you have the potential for narrowing and widening, but the more problematic conversion is a narrowing one. Primitive integers do not have decimals like floating point types either.

Also, if you understand floating point error you would also know why people use extreme caution when using floating point types for precision. When dealing with larger integers a long long is going to support much larger whole numbers too...

Code
int main(void)
{
    float x = 0.;
    for (float i = .10; i < 100.; i += .10)
    {
        x += i;
    }
    printf("%f\n", x);
    return 0;
}

The result might not be what you expect. https://docs.oracle.com/cd/E19957-01/806...dberg.html
Getting Started: C/C++
[C/C++/.NET/x86 ASM - Automation Programmer]
(Sep 6, 2017 07:23 AM)FaberCastell Wrote:  So my question is, how do i know when do i have to use (long long), or (long) or any other data type before the operation... I don't understand what's the point and when to use it.

In the example below, without (long long) the result ended up somehow being negative and incorrect.

Code
unsigned long long myNumber;

(loop)
myNumber+= (long long) pow(2, i);
(endofloop)


1. Use bitshifts for computing powers of two. You can do left bitshifts using << operator. For example, 2^18 (i.e. 2 to the power of 18) using 2 << 18. The bitshift operation will use lesser clock cycle, avoid inaccuracy, and will not use the FPU.
2. Initialize myNumber to 0, the default value is compiler-dependent, you don't want that.
3. You should identify the largest power you want to handle. For powers <= 32, use unsigned int. For powers <= 64, use unsigned long long int. If you want your code to be really portable, you can use sizeof(TYPE) * 8 to compute the number of bits in a integer TYPE.

ps: sizeof() macro returns the number of bytes in a data type.

I get your question. Try setting myNumber to 0. I think it will be corrected after doing that. LMK otherwise.


(Sep 6, 2017 01:20 PM)0xDEAD10CC Wrote:  Why do you think you need to? I already told you - you're not going to get a negative result from an unsigned type. When you cast things you have the potential for narrowing and widening, but the more problematic conversion is a narrowing one. Primitive integers do not have decimals like floating point types either.

Also, if you understand floating point error you would also know why people use extreme caution when using floating point types for precision. When dealing with larger integers a long long is going to support much larger whole numbers too...

Code
int main(void)
{
    float x = 0.;
    for (float i = .10; i < 100.; i += .10)
    {
        x += i;
    }
    printf("%f\n", x);
    return 0;
}

The result might not be what you expect. https://docs.oracle.com/cd/E19957-01/806...dberg.html

Last statement is not necessarily true. The point of floating points is representing large numbers with a sacrifice in accuracy. You can represent extremely large integers with double,
,.
(Sep 8, 2017 09:53 AM)Ronnie Coleman Wrote:  1. Use bitshifts for computing powers of two. You can do left bitshifts using << operator. For example, 2^18 (i.e. 2 to the power of 18) using 2 << 18. The bitshift operation will use lesser clock cycle, avoid inaccuracy, and will not use the FPU.
2. Initialize myNumber to 0, the default value is compiler-dependent, you don't want that.
3. You should identify the largest power you want to handle. For powers <= 32, use unsigned int. For powers <= 64, use unsigned long long int. If you want your code to be really portable, you can use sizeof(TYPE) * 8 to compute the number of bits in a integer TYPE.

ps: sizeof() macro returns the number of bytes in a data type.

I get your question. Try setting myNumber to 0. I think it will be corrected after doing that. LMK otherwise.



Last statement is not necessarily true. The point of floating points is representing large numbers with a sacrifice in accuracy. You can represent extremely large integers with double,

1. sizeof() is NOT a macro once again.
2. You shouldn't be hardcoding 8, you should use CHAR_BIT instead from <limit.h>
3. Which "last" statement? Is this not just what I finished saying:
Quote:floating points is representing large numbers with a sacrifice in accuracy


You can't represent extremely large integers with any floating point type because it is not an integer datatype. If you understand IEEE 754 they are represented from integers in the background.
Getting Started: C/C++
[C/C++/.NET/x86 ASM - Automation Programmer]
(Sep 9, 2017 12:57 PM)0xDEAD10CC Wrote:  1. sizeof() is NOT a macro once again.
2. You shouldn't be hardcoding 8, you should use CHAR_BIT instead from <limit.h>
3. Which "last" statement? Is this not just what I finished saying:

You can't represent extremely large integers with any floating point type because it is not an integer datatype. If you understand IEEE 754 they are represented from integers in the background.

Point taken. I understand IEEE 754 perfectly. I misunderstood your point.


I just meant to say that certain large numbers cannot be represented by unsigned 64-bit integer but can be represented by double. Probably not worth discussing.
,.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[C] by alt2600Nov 25, 2010 01:02 PM 10 165 Nov 25, 2010 01:02 PM
Last Post: Etheryte