Convert constant Double to Int in llvm IR - llvm

Given the following IR,
%1 = call double #llvm.pow.f64(double %conv, double 9.000000e+00)
when the fraction part of second argument is zero, I want to get it(second argument) in int type.
Can someone please suggest a method for this conversion?
Thank you in advance.

There are conversion instructions for this:
fptoui
fptosi
EDIT:
If you wish to convert llvm::ConstantFP, you can call getValueAPF() method, which would return you llvm::APFloat. See documentation on how to convert llvm::APFloat to integer.

Related

tgamma() long long typecasting

I am writing a function in which I have to calculate factorial of numbers and do operations on them.The return value of the function should be long long so I think it would be better to do all operations in long long format. If I am wrong please correct me.
The tgamma() function by itself returns the correct value in scientific notation. But the the value returned by tgamma() is sometimes 1 less than actual answer when the value returned by the function is typecasted to 'long long'.
int main()
{
std::cout<<"11!:"<<tgamma(12)<<std::endl;
std::cout<<"12!"<<tgamma(13)<<std::endl;
std::cout<<"13!"<<tgamma(14)<<std::endl;
std::cout<<"14!"<<tgamma(15)<<std::endl;
std::cout<<"15!"<<tgamma(16)<<std::endl;
std::cout<<"16!"<<tgamma(17)<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)tgamma(12)<<std::endl;
std::cout<<"12!"<<(long long)tgamma(13)<<std::endl;
std::cout<<"13!"<<(long long)tgamma(14)<<std::endl;
std::cout<<"14!"<<(long long)tgamma(15)<<std::endl;
std::cout<<"15!"<<(long long)tgamma(16)<<std::endl;
std::cout<<"16!"<<(long long)tgamma(17)<<std::endl;
return 0;
}
I am getting the following output:
11!:3.99168e+07
12!4.79002e+08
13!6.22702e+09
14!8.71783e+10
15!1.30767e+12
16!2.09228e+13
********************************
11!:39916800
12!479001599
13!6227020799
14!87178291199
15!1307674367999
16!20922789888000
The actual value of 15! according to this site is 1307674368000 but when I typecast tgamma(16) to long long, I get only 1307674367999. The thing is this discrepancy only appears for some numbers. The typecasted answer for 16! is correct - 20922789888000.
This function is for a competitive programming problem which is currently going on, so I can't paste the function and the solution I am developing to it here.
I would roll my own factorial function but I want to reduce the number of characters in my program to get bonus points.
Any tips on how to detect this discrepancy in typecasted value and correct it? Or maybe some other function that I can use?
Obviously, unless we have very unusual implementation, not all long long numbers can be exactly represented as double. Therefore, tgamma cannot store double values such that casting to long long would produce exact value. Simply there are more long long values than double values within long long interval.
If you want exact long long factorial, you should implement it yourself.
On top of this, if you want precision, you transform double to long long not as (long long)x, but as (long long)round(x), or (long long)(x+0.5), assuming x is positive.
Casting from a floating point type to an integral type truncates. Try (long long) roundl(tgammal(xxx)) to get rid of integer truncation error. This is also using long doubles so it may give you more digits.
#include <math.h>
#include <iostream>
int main(){
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
return 0;
}
Gives:
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000
********************************
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000

Converting int to long C++

This fuction convert Decimal number to Binary (I've founded it on Internet)
foo(long dec)
{
long int rem,i=1,sum=0;
do
{
rem=dec%2;
sum=sum + (i*rem);
dec=dec/2;
i=i*10;
} while(dec>0);
return sum;
}
As I found out, when I change type "long" to "int", the function doesn't work for number bigger than 1023. The problem is I have to run this function with integer argument (It has to be foo(int dec)). I have tried to use static_cast but I've failed.
error: cannot convert ‘long int’ to ‘std::ios_base&(std::ios_base&)’ in assignment|
Is there any way to bypass that or maybe change this function somehow.
Thank you for you help.
First of all, this function doesn't exactly "convert decimal to binary". Instead, it will convert a number such that if you print out the result in base 10, then it looks like the binary representation of the number.
Secondly this function definition is invalid because you did not specify a return type.
Of course, if you change long to int in the parameter list, and add int as return type (and your system has smaller ints than longs - some don't) then it will not work for as may numbers.
For example, if your system has 32-bit ints then 1111111111 is the largest output that will work, and that comes from input 1023.
I don't know what you're talking about with the static_cast and ios_base error, you must have done something unrelated to this function.
Make sure you define the type that the function is returning in the function definition, and make sure foo is taking a long int as an argument.
long int foo(long int) {
code...
}

C++ winapi LONG to std double

I'm messing with some stuff in the winapi and I'm trying to get the cursor position with GetCursorPos(POINT) and store the x and y in a list. The list I have is:
double cursor[2];
So you might already see what I need. POINT's x and y values are winapi LONGS. I can cast em to an std long easy just with
POINT cPos;
(long) cPos.x;
but I can't cast it to a double. I need it to be in double format because of the math that I'm going to apply to it so that everything works alright.
Basically what I get when casting is it just gives me 0
Can anyone help me out?
You don't need to cast from LONG to double. You can simply write:
cursor[0] = cPos.x;
cursor[1] = cPos.y;
It is not necessary to do intermediate cast. I.e. use (double)cPos.x and (double)cPos.y in your math expression without this cursor[2] array.

Casting a Z3 integer expression to a C/C++ int

I'm new to Z3 and searched for the answer to my question here and on Google. Unfortunately, I was not successful.
I'm using the Z3 4.0 C/C++ API. I declared an undefined function d: (Int Int) Int, added some assertions, and computed a model. So far, that works fine.
Now, I want to extract certain values of the function d defined by the model, say d(0,0). The following statement works, but returns an expression rather than the function value, i.e., an integer, of d(0,0).
z3::expr args[] = {c.int_val(0), c.int_val(0)};
z3::expr result = m.eval(d(2, args));
The check
result.is_int();
returns true.
My (hopefully not too stupid) question is how to cast the returned expression to a C/C++ int?
Help is very appreciated. Thank you!
Z3_get_numeral_int is what you're looking for.
Here is an excerpt from the docummentation:
Z3_bool Z3_get_numeral_int(__in Z3_context c, __in Z3_ast v, __out int * i)
Similar to Z3_get_numeral_string, but only succeeds if the value can fit in a
machine int. Return Z3_TRUE if the call succeeded.
You should be careful though. Z3's integer is mathematical integer which can easily exceed the range of 32-bit int. In that sense, using Z3_get_numeral_string and parsing string to big integer is a better option.

Issues while printing float values

#include<stdio.h>
#include<math.h>
int main()
{
float i = 2.5;
printf("%d\n%d\n%d",i,i,i);
}
When I compile this using gcc and run it, I get this as the output:
0
1074003968
0
Why doesn't it print just
2
2
2
You're passing a float (which will be converted to a double) to printf, but telling printf to expect an int. The result is undefined behavior, so at least in theory, anything could happen.
What will typically happen is that printf will retrieve sizeof(int) bytes from the stack, and interpret whatever bit pattern they hold as an int, and print out whatever value that happens to represent.
What you almost certainly want is to cast the float to int before passing it to printf.
The "%d" format specifier is for decimal integers. Use "%f" instead.
And take a moment to read the printf() man page.
The "%d" is the specifier for a decimal integer (typically an 32-bit integer) while the "%f" specifier is used for decimal floating point. (typically a double or a float).
if you only want the non-decimal part of the floating point number you could specify the precision as 0.
i.e.
float i = 2.5;
printf("%.0f\n%.0f\n%.0f",i,i,i);
note you could also cast each value to an int and it would give the same result.
printf("%d\n%d\n%d",int(i),int(i),int(i));
%d prints decimal (int)s, not (float)s. printf() cannot tell that you passed a (float) to it (C does not have native objects; you cannot ask a value what type it is); you need to use the appropriate format character for the type you passed.