pascal to c++: trunc - c++

I have old pascal code
var i : longint;
m : double;
begin
.....
i := trunc(m);
I have to convert it to C++ code.
An obvious thing here is to write
double m;
int i;
.....
i = static_cast<int>(std::trunc(m));
But the problem here is than pascal's trunc returns integer
function trunc(
d: ValReal
):Int64;
while c++'s trunc returns double.
Is it possible that for example trunc(2.3) will return 1.999999999999
and static_cast will make it 1 instead of 2? If yes is it correct to use static_cast without trunc to get same pascal's behavior?
i = static_cast<int>(m);

When you convert a floating-point value to an integer value in C++, the floating-point value is truncated automatically.
Take a look at the following simple example:
#include <iostream>
int main()
{
double d = 12.98;
int i = d;
std::cout << "i = " << i << '\n';
}
The above program will print
i = 12
Conversions like these are done implicitly by the compiler. For more information please read about implicit conversions (specifically read about floating-integral conversions).
However, it's important to note (from the linked reference):
If the value cannot fit into the destination type, the behavior is undefined
So the floating point value, after truncation, must fit into the integer type on the left-hand side of the assignment.

All integers (and most longs?) are exactly representable in double. A function like trunc that's defined to return an integer in mathematical sense will never return something that's not an exact integer if its proper return value can be represented in double.

Related

How significant is (int) within a statement?

If I have:
#include <iostream>
int main()
{
float a,b,c;
b = 7;
c = 2;
a = (int) (b / c);
std::cout << a;
}
Does (int) only affect the data type during cout so that 'a' can be printed as an integer or does it affect 'a' as a variable changing it to an 'int'?
Does (int) only affect the data type during cout so that a can be printed as an integer or does it affect a as a variable changing it to an int?
Neither.
a = (int)(....);
only changes what is assigned to a. In this case it truncates the floating point number and assigns the integral part of the number to a.
It does not change how a is processed in cout << a. You will notice a truncated value in the output. However, the reason for that is that a truncated value got assigned to a in the previous statement not because cout << a is processed differently.
It does not change the type of a to an int. The type of a variable cannot be changed in C++. It remains unchanged for the entire life of the program.
In this particular case it converts from a float value, the result of b/c into an int, then as a is still a float, converts it back to a float.
This is an easy, if sometimes problematic way of rounding something to an integer value.
Remember that in C++ variables never change their fundamental type. Something defined as a float stays a float forever. You can force other values into the same memory location, you can recast them, but the variable itself always has a fixed intrinsic type.
Cast does not change the type of a variable the casted value is assigned to.
In your case, result of b/c is casted (truncated) to an int, which is then promoted to float.
In this case the int is a cast datatype.
What the computer are thinking
Inside the main function:
float a, b, c;
Declaring 3 variables of data_Type float.
b = 7;
c = 5;
Assigned value of 7 to b and value 5 to c.
a = (int) (b / c);
A is equal to b/c ==> 7/5 ==> 1.4, wait, the programmer asked to cast the data as int so 1.4 ==> 1
std::cout << a;
Output: 1.0
Hope this help

I was trying to make an output/input calculator with C++

I am self teaching my self teaching myself C++
but I am having a trouble make a simple input/output calculator.
Here is what I have come up with:
#include <iostream>
using namespace std;
int main()
{
cout << "THIS IS TEST CALCULATOR!" << endl;
int fn,sn,dvi; //fn- FIRST NUMBER, sn - SECOND NUMBER
cout << "Please type in the first number: " << endl;
cin >> fn;
cout << "Please type in the second number: " << endl;
cin >> sn;
cout << "Please choose type ( type in one: division, multiplication, subtraction, addition or modulus): "<< endl; //Asks for the type on calculation; needs to type in one.
std::string tp;
cin>>tp;
dvi = (fn/sn); // division
if (tp == "division"){
cout<<fn<<" divide by "<<sn<<" is "<<dvi<< endl;
}
}
result:
8/6 = 1.333333... not 1
You are performing integer division, and therefore 8/6 is 1. If you want floating point arithmetic, you could change fn,sn and dvi to float instead of int, or you could simply cast one or both of the arguments to a float (or double).
See this question for more in-depth answers.
Since the decalred variable type is int you will always get the floor of number.
All three should be of type float or double. Else dvi can be of this type and typecast the fn and sn to same type (float/double) during division.
When dividing integers you get integer values not decimal ones. To solve your problem you either declare them float or double or cast the operation.
double dvi = ((double)fn / (double)sn); // division
Instead of declaring fn,sn,dvi as ints, you should declare them as doubles:
double fn,sn,dvi;
Otherwise, dividing integers by integers in C++ will truncate the numbers to a smaller whole number. For example: 5/3 would equal 1, even though in reality it equals 1.6667. C++ will not round up to 2.0, it will round down to 1.
Another workaround for this issue if you're not using variables is to add the decimal to whole numbers so that the compiler recognizes them as doubles. For example: 5.0/2.0 = 2.5
The problem in your code is that you are dividing 2 variables that are of type int, and storing it in a variable that is also of type int. All three variables:
fn
sn
dvi
are of type int in your code. An int variable only stores a whole integer number, ranging from positive infinity to negative infinity. This means that when you divide 2 numbers that do not produce an integer, the floating point value is rounded off so that it can be stored in the int variable, which in your case is dvi. In addition, even if dvi alone is of data type float, your division will still round to a whole number as you have divided two variables of data type int, namely fn and sn, and in c++, when two integers are divided, the end result is always rounded off regardless of the data type of the variable it will be stored in.
The easiest way to get around the problem is to change the declaration of these variables to:
double fn, sn, dvi;
NOTE: I use double here, as it can store a more precise value since it has 8 bytes allocated to it in contrast to 4 for a float.
This is the easiest way to get around your problem. Alternatively, we can use casting in the mathematical step of your code; in that case we would declare the variables as:
int fn, sn;
double dvi;
Then in the step where you divide the numbers, you can do the following:
dvi = (double)(fn/sn);
This is called casting; the compiler here is "forced" to treat the end result of this division as a double. In your case it will work, as you are dividing numbers, however, as a side note, it cannot be done in all cases (you cannot cast a string as a float for example). Here is a link if you want to learn more about casting:
Typecasting in C and C++
A third way, simpler than casting would be to do the following:
dvi = (fn/sn)*1.0;
This can be done only if dvi is of type float or double. Here, the mathematical operation involves a float, so all values are not of type int. As a result, the precision of the value is preserved with a decimal point, in your case, it will store 1.33333333333... instead of 1.
Sorry for the late reply, I couldn't get time to answer your question yesterday.

Confusion about float data type declaration in C++

a complete newbie here. For my school homework, I was given to write a program that displays -
s= 1 + 1/2 + 1/3 + 1/4 ..... + 1/n
Here's what I did -
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
int a;
float s=0, n;
cin>>a;
for(n=1;n<=a;n++)
{
s+=1/n;
}
cout<<s;
getch();
}
It perfectly displays what it should. However, in the past I have only written programs which uses int data type. To my understanding, int data type does not contain any decimal place whereas float does. So I don't know much about float yet. Later that night, I was watching some video on YouTube in which he was writing the exact same program but in a little different way. The video was in some foreign language so I couldn't understand it. What he did was declared 'n' as an integer.
int a, n;
float s=0;
instead of
int a
float s=0, n;
But this was not displaying the desired result. So he went ahead and showed two ways to correct it. He made changes in the for loop body -
s+=1.0f/n;
and
s+=1/(float)n;
To my understanding, he declared 'n' a float data type later in the program(Am I right?). So, my question is, both display the same result but is there any difference between the two? As we are declaring 'n' a float, why he has written 1.0f instead of n.f or f.n. I tried it but it gives error. And in the second method, why we can't write 1(float)/n instead of 1/(float)n? As in the first method we have added float suffix with 1. Also, is there a difference between 1.f and 1.0f?
I tried to google my question but couldn't find any answer. Also, another confusion that came to my mind after a few hours is - Why are we even declaring 'n' a float? As per the program, the sum should come out as a real number. So, shouldn't we declare only 's' a float. The more I think the more I confuse my brain. Please help!
Thank You.
The reason is that integer division behaves different than floating point division.
4 / 3 gives you the integer 1. 10 / 3 gives you the integer 3.
However, 4.0f / 3 gives you the float 1.3333..., 10.0f / 3 gives you the float 3.3333...
So if you have:
float f = 4 / 3;
4 / 3 will give you the integer 1, which will then be stored into the float f as 1.0f.
You instead have to make sure either the divisor or the dividend is a float:
float f = 4.0f / 3;
float f = 4 / 3.0f;
If you have two integer variables, then you have to convert one of them to a float first:
int a = ..., b = ...;
float f = (float)a / b;
float f = a / (float)b;
The first is equivalent to something like:
float tmp = a;
float f = tmp / b;
Since n will only ever have an integer value, it makes sense to define it as as int. However doing so means that this won't work as you might expect:
s+=1/n;
In the division operation both operands are integer types, so it performs integer division which means it takes the integer part of the result and throws away any fractional component. So 1/2 would evaluate to 0 because dividing 1 by 2 results in 0.5, and throwing away the fraction results in 0.
This in contrast to floating point division which keeps the fractional component. C will perform floating point division if either operand is a floating point type.
In the case of the above expression, we can force floating point division by performing a typecast on either operand:
s += (float)1/n
Or:
s += 1/(float)n
You can also specify the constant 1 as a floating point constant by giving a decimal component:
s += 1.0/n
Or appending the f suffix:
s += 1.0f/n
The f suffix (as well as the U, L, and LL suffixes) can only be applied to numerical constants, not variables.
What he is doing is something called casting. I'm sure your school will mention it in new lectures. Basically n is set as an integer for the entire program. But since integer and double are similar (both are numbers), the c/c++ language allows you to use them as either as long as you tell the compiler what you want to use it as. You do this by adding parenthesis and the data type ie
(float) n
he declared 'n' a float data type later in the program(Am I right?)
No, he defined (thereby also declared) n an int and later he explicitly converted (casted) it into a float. Both are very different.
both display the same result but is there any difference between the two?
Nope. They're the same in this context. When an arithmetic operator has int and float operands, the former is implicitly converted into the latter and thereby the result will also be a float. He's just shown you two ways to do it. When both the operands are integers, you'd get an integer value as a result which may be incorrect, when proper mathematical division would give you a non-integer quotient. To avoid this, usually one of the operands are made into a floating-point number so that the actual result is closer to the expected result.
why he has written 1.0f instead of n.f or f.n. I tried it but it gives error. [...] Also, is there a difference between 1.f and 1.0f?
This is because the language syntax is defined thus. When you're declaring a floating-point literal, the suffix is to use .f. So 5 would be an int while 5.0f or 5.f is a float; there's no difference when you omit any trailing 0s. However, n.f is syntax error since n is a identifier (variable) name and not a constant number literal.
And in the second method, why we can't write 1(float)/n instead of 1/(float)n?
(float)n is a valid, C-style casting of the int variable n, while 1(float) is just syntax error.
s+=1.0f/n;
and
s+=1/(float)n;
... So, my question is, both display the same result but is there any difference between the two?
Yes.
In both C and C++, when a calculation involves expressions of different types, one or more of those expressions will be "promoted" to the type with greater precision or range. So if you have an expression with signed and unsigned operands, the signed operand will be "promoted" to unsigned. If you have an expression with float and double operands, the float operand will be promoted to double.
Remember that division with two integer operands gives an integer result - 1/2 yields 0, not 0.5. To get a floating point result, at least one of the operands must have a floating point type.
In the case of 1.0f/n, the expression 1.0f has type float1, so the n will be "promoted" from type int to type float.
In the case of 1/(float) n, the expression n is being explicitly cast to type float, so the expression 1 is promoted from type int to float.
Nitpicks:
Unless your compiler documentation explicitly lists void main() as a legal signature for the main function, use int main() instead. From the online C++ standard:
3.6.1 Main function
...
2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a declared return type of type int, but otherwise its type is implementation-defined...
Secondly, please format your code - it makes it easier for others to read and debug. Whitespace and indentation are your friends - use them.
1. The constant expression 1.0 with no suffix has type double. The f suffix tells the compiler to treat it as float. 1.0/n would result in a value of type double.

Is a float guaranteed to be preserved when transported through a double in C/C++?

Assuming IEEE-754 conformance, is a float guaranteed to be preserved when transported through a double?
In other words, will the following assert always be satisfied?
int main()
{
float f = some_random_float();
assert(f == (float)(double)f);
}
Assume that f could acquire any of the special values defined by IEEE, such as NaN and Infinity.
According to IEEE, is there a case where the assert will be satisfied, but the exact bit-level representation is not preserved after the transportation through double?
The code snippet is valid in both C and C++.
You don't even need to assume IEEE. C89 says in 3.1.2.5:
The set of values of the type float is a subset of the set of values
of the type double
And every other C and C++ standard says equivalent things. As far as I know, NaNs and infinities are "values of the type float", albeit values with some special-case rules when used as operands.
The fact that the float -> double -> float conversion restores the original value of the float follows (in general) from the fact that numeric conversions all preserve the value if it's representable in the destination type.
Bit-level representations are a slightly different matter. Imagine that there's a value of float that has two distinct bitwise representations. Then nothing in the C standard prevents the float -> double -> float conversion from switching one to the other. In IEEE that won't happen for "actual values" unless there are padding bits, but I don't know whether IEEE rules out a single NaN having distinct bitwise representations. NaNs don't compare equal to themselves anyway, so there's also no standard way to tell whether two NaNs are "the same NaN" or "different NaNs" other than maybe converting them to strings. The issue may be moot.
One thing to watch out for is non-conforming modes of compilers, in which they keep super-precise values "under the covers", for example intermediate results left in floating-point registers and reused without rounding. I don't think that would cause your example code to fail, but as soon as you're doing floating-point == it's the kind of thing you start worrying about.
From C99:
6.3.1.5 Real floating types
1 When a float is promoted to double or long double, or a double is promoted to long double, its value is unchanged.
2 When a double is demoted to float, a long double is demoted to double or float, or a value being represented in greater precision and range than required by its semantic type (see 6.3.1.8) is explicitly converted to its semantic type, if the value being converted can be represented exactly in the new type, it is unchanged...
I think, this guarantees you that a float->double->float conversion is going to preserve the original float value.
The standard also defines the macros INFINITY and NAN in 7.12 Mathematics <math.h>:
4 The macro INFINITY expands to a constant expression of type float representing positive or unsigned infinity, if available; else to a positive constant of type float that overflows at translation time.
5 The macro NAN is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN.
So, there's provision for such special values and conversions may just work for them as well (including for the minus infinity and negative zero).
The assertion will fail in flush-to-zero and/or denormalized-is-zero mode (e.g. code compiled with -mfpmath=sse, -fast-math, etc, but also on heaps of compilers and architectures as default, such as Intel's C++ compiler) if f is denormalized.
You cannot produce a denormalized float in that mode though, but the scenario is still possible:
a) Denormalized float comes from external source.
b) Some libraries tamper with FPU modes but forget (or intentionally avoid) setting them back after each function call to it, making it possible for caller to mismatch normalization.
Practical example which prints following:
f = 5.87747e-39
f2 = 5.87747e-39
f = 5.87747e-39
f2 = 0
error, f != f2!
The example works both for VC2010 and GCC 4.3 but assumes that VC uses SSE for math as default and GCC uses FPU for math as default. The example may fail to illustrate the problem otherwise.
#include <limits>
#include <iostream>
#include <cmath>
#ifdef _MSC_VER
#include <xmmintrin.h>
#endif
template <class T>bool normal(T t)
{
return (t != 0 || fabsf( t ) >= std::numeric_limits<T>::min());
}
void csr_flush_to_zero()
{
#ifdef _MSC_VER
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
#else
unsigned csr = __builtin_ia32_stmxcsr();
csr |= (1 << 15);
__builtin_ia32_ldmxcsr(csr);
#endif
}
void test_cast(float f)
{
std::cout << "f = " << f << "\n";
double d = double(f);
float f2 = float(d);
std::cout << "f2 = " << f2 << "\n";
if(f != f2)
std::cout << "error, f != f2!\n";
std::cout << "\n";
}
int main()
{
float f = std::numeric_limits<float>::min() / 2.0;
test_cast(f);
csr_flush_to_zero();
test_cast(f);
}

Purpose of a ".f" appended to a number?

I saw 1/3.f in a program and wondered what the .f was for. So tried my own program:
#include <iostream>
int main()
{
std::cout << (float) 1/3 << std::endl;
std::cout << 1/3.f << std::endl;
std::cout << 1/3 << std::endl;
}
Is the .f used like a cast? Is there a place where I can read more about this interesting syntax?
3. is equivalent to 3.0, it's a double.
f following a number literal makes it a float.
Without the .f the number gets interpreted as an integer, hence 1/3 is (int)1/(int)3 => (int)0 instead of the desired (float)0.333333. The .f tells the compiler to interpret the literal as a floating point number of type float. There are other such constructs such as for example 0UL which means a (unsigned long)0, whereas a plain 0 would be an (int)0.
The .f is actually two components, the . which indicates that the literal is a floating point number rather than an integer, and the f suffix which tells the compiler the literal should be of type float rather than the default double type used for floating point literals.
Disclaimer; the "cast construct" used in the above explanation is not an actual cast, but just a way to indicate the type of the literal.
If you want to know all about literals and the suffixes you can use in them, you can read the C++ standard, (1997 draft, C++11 draft, C++14 draft, C++17 draft) or alternatively, have a look at a decent textbook, such as Stroustrup's The C++ Programming Language.
As an aside, in your example (float)1/3 the literals 1 and 3 are actually integers, but the 1 is first cast to a float by your cast, then subsequently the 3 gets implicitly cast to a float because it is a righthand operand of a floating point operator. (The operator is floating point because its lefthand operand is floating point.)
By default 3.2 is treated as double; so to force the compiler to treat it as float, you need to write f at the end.
Just see this interesting demonstration:
float a = 3.2;
if ( a == 3.2 )
cout << "a is equal to 3.2"<<endl;
else
cout << "a is not equal to 3.2"<<endl;
float b = 3.2f;
if ( b == 3.2f )
cout << "b is equal to 3.2f"<<endl;
else
cout << "b is not equal to 3.2f"<<endl;
Output:
a is not equal to 3.2
b is equal to 3.2f
Do experiment here at ideone: http://www.ideone.com/WS1az
Try changing the type of the variable a from float to double, see the result again!
3.f is short for 3.0f - the number 3.0 as a floating point literal of type float.
The decimal point and the f have a different purpose so it is not really .f
You have to understand that in C and C++ everything is typed, including literals.
3 is a literal integer.
3. is a literal double
3.f is a literal float.
An IEEE float has less precision than a double. float uses only 32 bits, with a 23 bit mantissa and an 8 bit exponent (plus a sign bit).
double gives you more accuracy, but sometimes you do not need such accuracy (e.g. if you are doing calculations on figures that are only estimates in the first place) and that given by float will suffice, and if you are storing large numbers of them (eg processing a lot of time-series data) that can be more important than the accuracy.
Thus float is still a useful type.
You should not confuse this with the notation used by printf and equivalent statements.