How to convert some long double to long int in c? - c

I'm trying to convert a double type variable to a long long int. The only way I know to do it is by casting. Althoulg it seems ok, I'm not receiving the number I wanted.
I post the code piece bellow:
double fator = 100000000;
long long int iLongitude = (long long int)(fLongitude*10000000);
The number I expected was -4396478167 and I'm getting -439647816, without the last digit.
Thanks for the help!

It seems you just need to add one more zero, and also round:
(long long int)(fLongitude*100000000 + 0.5);
Since casting truncates results, the + 0.5 will round up if the fractional part is larger than 0.5.

Related

What's the role of L in modulo 1000000007L?

When you're a total noob programming, a lot of things looks like magic,
so solving some classic problems at SPOJ using C language, I found one called DIAGONAL.
After some attempts I gave up and went searching for solutions and I found this one:
#include <stdio.h>
int main() {
int num_cases, i;
long long mod_by = 24*1000000007L;
scanf("%d", &num_cases);
long long n;
long long answer;
for(i = 0; i < num_cases; i++) {
scanf("%lld", &n);
long long x = (n*(n-1)) % (mod_by);
long long y = (x*(n-2)) % (mod_by);
long long z = (y*(n-3)) % (mod_by);
answer = z / 24;
printf("%lld\n", answer);
}
return 0;
}
At first glance I thought that L with the modulo was some kind of mistake made by the user who posted the code (haha who would mix numbers with letters this way?! nonsense! -thought the noob-), but when I fixed the (many) wrongs in my code and used this modulo, it didn't work without the magic L (I got Wrong Answer).
Then I substituted the L with the ASCII code number (because well, maybe it was that!) and it also didn't work.
Since then I'm trying to understand what is the logic behind this. How can I get the same results removing this L?
It's not like one just woke up in the morning and "uhm, maybe if I add this L it will work", but I just couldn't find other examples of this (random letter added to a large number for calculations) googling.
long long mod_by = 24*1000000007L; is a problem.
The L suffix insures the constant 1000000007 is at least of type long.1 Without the L, the type may have been int or long.
Yet since long may only be 32-bit, the ~36-bit product can readily overflow long math leading to undefined behavior (UB).
The assignment to a long long happens after and does not affect the type nor range of the multiplication.
Code should use LL to form the product and protect against overflow.
long long mod_by = 24LL*1000000007;
// or
long long mod_by = 24*1000000007LL;
In general, make certain the calculation occurs at least with the width of the destination.
See also Why write 1,000,000,000 as 1000*1000*1000 in C?.
1 In OP's case, apparently int is 32-bit and long is 64-bit so code "worked" with a L and failed without it. Yet porting this code to a 32-bit long implementation, code fails with or without an L. Insure long long math with an LL constant.
The L suffix when applied to an integer constant means the constant has type long.
This is done to prevent overflow when the value is multiplied by 24. Without the suffix, two constants of type int are multiplied giving an int result. Assuming 32 is 32 bits, the result will overflow the range of an int (231-1) causing undefined behavior.
By making the constant have type long, assuming a long is 64 bits, it allows the multiplication to be done using and type and therefore not cause overflow and give you the correct value.
L is a suffix that means that the number is of type long, otherwise it will default to type int that means the result of the operation 24 * 1000000007 will also be of type int.
As an int is usually 4 bytes in size the result will overflow, this happens before it being assigned to mod_by, and for that reason it invokes undefined behavior.
As the result of the arithmetic operation is converted to the larger type, e.g:
int * int = int
int * long = long
For the result of the operation to be of type long one of the operands must also be of type long.
Note that long is not guaranteed to have 8 bytes in size, the minimum allowed size for a long is 4 bytes, so you can invoke the same undefined behavior deppending on the platform where you compile your program.
Using LL for long long will be more portable.

Why am I getting a negative value?

There is some mistake in power function of my code it returns correct answer for small values but gives wrong answer for large values.
#include<stdio.h>
long long MOD= 1000000007;
long long power(long long i,long long j)
{
if(j==0)
return 1;
long long d;
d=power(i,j/(long long)2);
if(j%2==0)
return (d*d)%MOD;
else
return (d*d*i)%MOD;
}
int main()
{
long long inv=1;
inv=power(25,MOD-2)%MOD;
printf("%lld\n",inv);
}
Your arithmetic overflowed the values representable in a long long in your C implementation.
Also, you are working on a challenge problem or homework which has been discussed numerous times on Stack Overflow, as you can see by searching for “1000000007”.
You need to be careful with (d*d*i)%MOD;, because more than one operation without modulo is incorrect, taking precision and risk of overflowing in account. To be strictly correct you need to write
return ((d*d)%MOD * i)%MOD;
Even in this case I assumed i == i%MOD
EDIT: I take an example :
log2((MOD-1)x(MOD-1)x25) = log2(1000000006x1000000006x25) = 64.438
Which means you will be overflowing during your computation with this input.
range of signed long long is -2^63 to (2^63 - 1) and the last bit is used to store sign . In your case when multiplication of large numbers is evaluated than your result will overflow and 64th bit of number(which stores sign) will get value 1 (which means -ve value).
That's the reason you are getting negative value as output.
Read this

Printing a very large whole number in C

I've stored a very large number in a float variable, but when I print it I want to only display the whole number part and nothing after the decimal point.
For numbers in the int or long range, I would do a casting but this hasn't helped me because the number I want to print is too long for int or long.
I've looked at this explanation: http://www.cprogramming.com/tutorial/printf-format-strings.html but I haven't succeeded in solving this.
this is my code and my attempt to do the casting:
double sum=552074001368;
long long_sum;
long_sum = (long)(sum); //int casting for double "add"
if(sum>=0) printf("=\n%ld\n",long_sum);
else printf("=\n%ld\n",-long_sum);
I don't want to use a specific precision like printf("%15f") because this variable fluctuates and is sometimes very short like 4 digits.
Use the precision modifier .0 and print the floor of the number:
printf("%.0f\n", floor(sum));
(Or the floor of the abs, if you want only the magnitude, as in your example code.)
I think what you're after is %.0f. For example:
#include <stdio.h>
int main(){
double x = 1234.567;
printf("%.0f", x);
return 0;
}
...prints:
1235
Why are you casting to long at all? Use the printf format specifiers to control what and how many characters are printed.
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Remember that both the width and the precision can be specified by a variable and doesn't have to be known at compile time:
printf("=\n%.*lf\n", 4, sum); // print 4 places behind the decimal point
int i;
i = 5;
// print only the whole number part of sum and output at least i characters,
// pad with leading spaces if number requires fewer than i characters
printf("=\n%*.*lf\n", i, 0, sum);
This line is problematic:
double sum=552074001368;
Since that is an integer literal, the compiler will first check if the number will fit in an int, then long, then long long. If it won't fit in long long I suspect you'll get either a compiler error or undefined behavior wrap-around, I'm not sure of which.
If your compiler supports long long, then the code will work and the number will be stored in a temporary long long (which will be optimized away). This long long is then stored inside a double.
Instead, write like this:
double sum=552074001368.0;
The .0 syntax gives you a double floating point literal without involving integer types at all.
double sum=552074001368LL;
long long long_sum;
long_sum = (long long)(sum);
if(sum>=0) printf("=\n%lld\n",long_sum);
else printf("=\n%lld\n",-long_sum);

Recursive fibonacci

I am trying to generate Fibonacci series and provided the code for the same below. When I run this code for smaller values, it outputs correct results. However, when I try and calculate series for a number say '50', it out puts correct results upto the 47th number and result for 48,49 and 50th term are incorrect. I tried using unsigned long int as well but it did not correct the results. Can some please suggest what am I doing wrong here.
Thanks.
#include<stdio.h>
unsigned long long int fibr(unsigned long long int);
int main(){
unsigned long long int n;
printf("Enter a number\n");
scanf("%llu",&n);
//res=fibr(n);
while(n>=0){
printf("%llu\n",fibr(n));
n--;
}
}
unsigned long long int fibr(unsigned long long int n){
if((n==0)||(n==1))
return n;
else return fibr(n-1)+fibr(n-2);
}
'After the suggestions , I incorporated unsigned long long int. Have modified the code above but now it gives a seg fault. Any hints please. I am not allowed to use any other library except the standards one available. '
Did you try using unsigned long long?
Here's the answer to your second question:
I think you had this problem from the beginning:
while(n>=0){
is an infinite loop since n is an unsigned integer. n will go negative due to the decrement. But since it's unsigned, it will wrap around and cause a stack-overflow in your recursion.
Also, your algorithm is probably slowest way to do this. It runs in exponential time. So it will take a very long time to run it when n is big.
A better way is just this:
int n = 48;
return (unsigned long long)(pow(1.6180339887498948,n) * 0.44721359549995794 + 0.5);
This method will run in constant time. :)
C data types are limited in size. So if you use int, long or long long, at some point, your result will overflow, due to the fast-growing nature of fibonacci-numbers.
To store such big numbers, you'll need some BigInteger implementation. Have a look at “BigInt” in C? for this.
You get integer overflow. For unsigned int the largest possible value is 4294967295, but 48th Fibonacci number is 4807526976.
Converting fibr() to memoize its results reduces the running time for fibr(90) to a few milliseconds on my machine. Switching from recursion to iteration should have similar results.

C : erroneous output for "(long long int) = (long long int) * (double)"?

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);
long long int out = A + B*D;
printf("%lld",out);
This gives result : -2147483648
I am not able to figure out why (it should be a positive result).
Can somebody help?
maybe you have to specify those constants as "long long" literals? e.g. 3289168178315264LL
What compiler/operating system are you using? I ran your code using Visual C++ 2008 Express Edition on Windows XP and IT WORKS - answer: 6578336356630528 (this is a 53-bit number, so it just fits inside a double).
I also tried two variations to see if the order of operations mattered:
long long int out = A;
out+=B*D;
long long int out = B*D;
out+=A;
These both work as well!
Curious.
My guess is that the compiler needs to round the result from "A+B*D" to an integer first, because you're storing the result inside an int field. So basically, you're having a datatype conflict.
Both A and B are still valid numbers for a long long int, which is 8 bytes long. You could even multiply them by 1.000 and still have valid long long int values. In some other languages it's also known as the int64.
A double, however, is also 64-bits but part of those are used as exponent. When you multiply a double with an int64, the result would be another double. Adding another int64 to it still keeps it a double. Then you're assigning the result to an int64 again without using a specific rounding method. It would not surprise me if the compiler would use a 4-bit rounding function for this. Am even amazed that the compiler doesn't puke and break on that statement!
Anyways, when using large numbers like these, you have to be extra careful when mixing different types.
Your answer (have to verify) calcuates successfully, however, it causes an overflow into the sign bit, which makes the answer negative. Solution : make all your variables unsigned.
Why:
Numbers are stored as series of bits in you computer's memory. The first bit in such a series, when set means that you number is negative. So the calculation works, but overflows into the sign bit.
Recommendation:
If you're working with numbers this big, I recommend you to get a multiprecision arithmetic library. 'T will save you a lot of time and trouble.
The parameter to sqrt should be double.
#include <math.h>
double sqrt( double num );
And also we should explict cast the result from B * D to long long.
long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5.0);
printf("%f\n",D);
long long int out = A + (long long) (B * D);
printf("%lld",out);

Resources