I'm trying to cast a column in double type into float, so I'll be able to use the round() function. I tried different way to do it but it doesn't work in my case.
df=EAS3
gap_AZ= (col('KPI_2') - col('average'))/col('average')*100).cast(FloatType())
EAS3 = (EAS3.withColumn('GAP', lit(gap_AZ)))
I expect to have gap_AZ as a float type column. But when I use FloatType it forces it to STRING type.
Is anyone know what happen?
Thank you
You can try this UDF function:
from pyspark.sql.types import FloatType
tofloatfunc = udf(lambda x: x,FloatType())
changedTypedf = df.withColumn("Column_name", df["Column_name"].cast(FloatType()))
Related
Problem: In a homework problem (it is to be done on paper with a pen so no coding) I must determine the type and value of an addition performed in C++.
1 + 0.5
What I've answered is:
Type float (because I thought that integer + float = float)
Value 1.5 (As far as I know when two different datatypes are added,
the result of the addition is going to be converted to the datatype that does not loose any information.)
Solution says:
Type: double
Value: 1.5
My Question: Why is 0.5 a double and not a float? How can I distingish between a float and a double? I mean, 0.5 looks to me like a float and a double.
First of all, yes. integer + float = float. You are correct about that part.
The issue is not with that, but rather your assumption that 0.5 is a float. It is not. In C++, float literals are followed by an f meaning that 0.5f is a float. However, 0.5 is actually a double. That means that your equation is now:
integer + double = double
As you can see, this result is a double. That is why the correct answer to your question is that the resulting type is a double.
By the way, to clear the record, technically what's going on here isn't integer + double = double. What is happening is that the 1 is falling subject to implicit conversion. Essentially, the 1 is converted to a double, since the other side of the operation is a double as well. This way, the computer is adding the same types and not different ones. That means that the actual addition taking place here is more like:
double + double = double
In C++, floating point literals without a type suffix are double by default. If you want it to be float, you need to specify the f suffix, like 0.5f.
While declaring a variable of type float, is it necessary to write f towards the end of the value? For example, float amount = .01 and float amount = 0.01f, here what does the f mean and how does it make any difference?Also, what is the role of #include library file here.
It's not necessary: the compiler will make an appropriate numerical conversion for you.
0.01f is a literal of float type, whereas 0.01 is a double type.
Occasionally you need to descriminate explicitly especially when working with templates or overloaded functions:
void foo(const float&){
// Pay me a bonus
}
void foo(const double&){
// Reformat my disk
}
int main(){
foo(1.f);
}
Finally, if you're leading towards using a float over a double, then do read through this: Is using double faster than float?
It depends on how you define your variable. When specifying the type float in the definition, adding a trailing f is not necessary:
float amount = 0.1; /* This is fine, compiler knows the type of amount. */
Adding a superfluous literal here (float amount = 0.1f;) might even be considered bad practice, as you repeat the type information, resulting in more edits when the type is changed.
In the context of type deduction though, you have to give the f literal:
auto amount = 0.1f; /* Without the literal, compiler deduces double. */
There are more subtle contexts in which type deduction occurs, e.g.
std::vector<float> vecOfFloats;
/* ... */
std::accumulate(vecOfFloats.cbegin(), vecOfFloats.cend(), 0.1f);
Here, the third argument is used to deduce the type on which std::accumulate operates. If you just call it like std::accumulate(..., 0.1);, a double to float conversion takes place for every element in vecOfFloats.
.01 is a double literal. There is an implicit conversion to float in the initialisation
float amount = .01;
.01f is a float literal. There is no conversion in the initialisation
float amount = .01f;
That depends...
You can do for example:
1)
float f = 3.14f;
In this case the literal 3.14 is explicitly given as a float... so everything is ok
2)
float f = 3.14;
In this case 3.14 is actually a double, but the variable f is declared as a float...so when compiling, the number will be casted to a float with the loss precision consequences of that case...
You could since c++11
auto f = 3.14;
Or auto f{3,14};
In both cases the compiler takes exactly the type of the literal...(both are doubles)
I would like to remove float leftovers while retaining its type.
(i.e 3.14159f should become 3.0f)
What I can do so far is casting the type twice.
float f = 3.14159f;
float r = static_cast<float>(static_cast<int>(f));
Is this the correct way to do it? or is there any simpler way?
Thank you in advance.
The operation of "removing leftovers" is called truncation. C++ provides std::trunc function to do it (include <cmath> header):
float r = std::trunc(f);
Is this the correct way to do it?
No.
or is there any simpler way?
One single cast should be sufficient:
float r = static_cast<int>(f);
Also as #Baum mit Augen said in their comment:
"This fails for values that don't fit in an int"
So using std::trunc() solves that problem with correct error handling.
That is a correct way to do that, but you can also use floor:
std::cout << std::floor(3.14f); // prints 3
Is there any predefined type which can switch between float and double in some specific condition.
For example, some type, I would like this type be float; sometimes I need this type becomes double.
Use always double, it is recommended everywhere, if you don't have huge arrays in your program. This is a thing that I learned in programming competitions and because of which I failed many times previously because of precision problems.
It is not clear what you want to do. As #thecoder suggested the simplest option is to just use double. To convert it to float you just assign it:
double d = 0.1;
float f = d;
However, if you need to write code that must work both for float and double, use a template:
template<NumberT>
NumberT sum(NumberT first, NumberT second) {
return first + second;
}
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.