Is there an "inverted" trunc function in C or C++? [duplicate] - c++

This question already has answers here:
c++ rounding of numbers away from zero
(4 answers)
Closed 3 years ago.
Is there a function in C or C ++ - similar to trunc - that rounds off negative numbers and rounds up positive numbers?
Like in this example:
-3.3 to -4 or 2.1 to 3
I could only find the "inverse" function trunc. But can hardly believe that this does not exist. Do I really have to first query the positivity via if and then round it up accordingly? I need this because I have the sign of the scalar product between two vectors. So either 1, -1 or 0.

First, you can use an inline conditional to either return the floor or the ceil. Here:
#include <math.h>
inline double InvertedTrunc(double Number) {
return Number < 0 ? floor(Number) : ceil(Number);
}
Another approach to achieve this functionality is just truncating the number, and increasing its absolute value by one. This will also work. Does not require math.h However, it is not recommended for large numbers because of overflow:
inline double InvertedTrunc(double Number) {
return (Number == (int)Number ? Number : ((int)Number)+(Number < 0 ? -1 : 1)); //casting to int truncates it
} //However, this option is susceptible to overflow, and it is not recommended for large numbers

Related

How I can solve C++ output negative numbers when using modulo? [duplicate]

This question already has answers here:
Fastest way to get a positive modulo in C/C++
(9 answers)
How to code a modulo (%) operator in C/C++/Obj-C that handles negative numbers
(16 answers)
Closed 2 years ago.
In a code written by me, I have used both below functions to calculate mod of displayed negative number.
fmod(-10,11)
(-10, 11)
Though the correct answer is 1. It always displays the answer -10 in c++. How I can solve it?
From cppreference.com:
double fmod (double numer, double denom);
The floating-point remainder of the division operation x/y calculated by this function is exactly the value x - n*y, where n is x/y with its fractional part truncated.
The returned value has the same sign as x and is less than y in magnitude.
In your case it is -10 - (-10)/11 * 11 = -10 - 0 * 11 = -10, which is correct for that implementation of fmod. If you need another answer, you should implement your own version, as modulo is defined in different ways for negative numbers.

problem in using 'double' data type in for loops with fractional incrementation [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
I had a program which requires one to search values from -100.00 to +100.00 with incrementation of 0.01 inside a for loop. But the if conditions arent working properly even if code is correct...
As an example I tried printing a small section i.e if(i==1.5){cout<<"yes...";}
it was not working even though the code was attaining the value i=1.5, i verified that by printing each of the values too.
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
double i;
for(i=-1.00; i<1.00; i=i+0.01)
{
if(i>-0.04 && i<0.04)
{
cout<<i;
if(i==0.01)
cout<<"->yes ";
else
cout<<"->no ";
}
}
return 0;
}
Output:
-0.04->no -0.03->no -0.02->no -0.02->no -0.01->no 7.5287e-016->no 0.01->no 0.02->no 0.03->no
Process returned 0 (0x0) execution time : 1.391
(notice that 0.01 is being attained but still it prints 'no')
(also notice that 0.04 is being printed even if it wasn't instructed to do so)
use this if(abs(i - 0.01) < 0.00000000001) instead.
double - double precision floating point type. Usually IEEE-754 64 bit
floating point type
The crux of the problem is that numbers are represented in this format as a whole number times a power of two; rational numbers (such as 0.01, which is 1/100) whose denominator is not a power of two cannot be exactly represented.
In simple word, if the number can't be represented by a sum of 1/(2^n) you don't have the exact number you want to use. So to compare two double numbers calculate the absolute difference between them and use a tolerance value e.g. 0.00000000001 .
Doubles are stored in binary format. To cut things short fractional part is written as binary. Now let's imagine it's size is 1 bit. So you've two possible values (for fraction only): .0 and .5. With two bits you have: .0 .25 .5 .75. With three bits: .125 .25 .375 .5 .625 .75 .875. And so on. But you'll never get 0.1. So what computer does? It cheats. It lies to you, that 0.1 you see is 0.1. While it more looks like 0.1000000000000000002 or something like this. Why it looks like 0.1? Because formatting of floating point values has long standing tradition of rounding numbers, so 0.10000000000001 becomes 0.1. As a result 0.1 * 10 won't equal 1.0.
Correct solution is to avoid floating point numbers, unless you don't care for precision. If your program breaks, once your floating point value "changes" by miniscule amount, then you need to find another way. In your case using non-fractional values will be enough:
for(auto ii=-100; ii<100; ++ii)
{
if(ii>-4 && ii<4)
{
cout << (ii / 100.0);
if(ii==1)
cout<<"->yes ";
else
cout<<"->no ";
}
}

Why does "double i = 1/12;" yields to i = 0? [duplicate]

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 5 years ago.
I think the title says everything. I want to define a variable i as the fraction 1/12. However, i is 0.
double i = 1/12;
std::cout << i; // Output: 0
Or, more specific, I want to calculate a power of something:
im_ = std::pow((1 + i), (1/12)) - 1;
However, the compile evaluates (1/12) as 0 and thus the result is wrong.
Simple because 1/12 is evaluated as integer math, not floating point math.
1/12 becomes 0 because integer math does not take into account the decimal fractions.
To get the expected result you will need to write down the numbers as a floating point literal, like this: 1.0/12.0.
More details can be found here: Why can't I return a double from two ints being divided

Calculation returns zero instead of expected result [duplicate]

This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 9 years ago.
I am trying to do a simple calculation : ( (45/100) - (20+50)/200 )*(10+5)
I am expecting the answer to be 1.5 but when the programme is compiled , it shows 0.
Can someone figure this out for me
#include <iostream>
using namespace std;
int main()
{
float CivIndex = ( (45/100) - (20+50)/200 )
*(10+5);
cout<<CivIndex; // expect 1.5 but getting 0
}
Integer division!
(45 / 100) equals 0 when evaluated as an integer, not 0.45 as you'd been hoping.
Make either numerator or denominator a float to get the expected result:
(45.0 / 100)
What you are doing is integer division, and integer division rounds the result to the closest integer. To correct your code, change it to:
#include <iostream>
using namespace std;
int main()
{
float CivIndex = ( (45.0/100.0) - (20.0+50.0)/200.0 )
*(10.0+5.0);
cout<<CivIndex; // expect 1.5 but getting 0
}
Note: not all .0 are needed, but just put them to be sure.
You are doing integer division.
Specify it as float constants
float CivIndex = ( (45./100) - (20+50)/200. )*(10+5);
^ Notice decimal points^
All your constants are ints, therefore, the compiler is doing integer math. 45/100 as an int is 0. So is 70/200. 0 - 0*15 = 0. You need to tell the compiler that your constants are floats: 20f, or 20.0 would both work. (For each operation, if at least one constant is a float, the operation will be treated as floating point math.)
In C and several other languages diving two integers result in an integer (integral division). That is 45 / 100 in your code will result in 0 instead of the expected 0.45
The fix is simple: convert one of the operands to floating point.
float CivIndex = ( (45/100.0) - (20+50)/200.0 )
*(10+5);
You are hoping the integer division as 0.45 but that is actually 0
Try to change this as:
float CivIndex = ( (45.0/100) - (20.0+50.0)/200 )
*(10+5);
You are essentially evaluating an expression containing only integers. So the
result will be an integer.
You can use casts on the final result of the integer expression.
e.g..
int a=20;float b; b=(float)a;cout<<"b: "<<b;
Please confirm the syntax.
Or as stated above, you can also make one of you operands as a float/double(if your requirement permits).

Why do simple doubles like 1.82 end up being 1.819999999645634565360? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does Visual Studio 2008 tell me .9 - .8999999999999995 = 0.00000000000000055511151231257827?
c++
Hey so i'm making a function to return the number of a digits in a number data type given, but i'm having some trouble with doubles.
I figure out how many digits are in it by multiplying it by like 10 billion and then taking away digits 1 by 1 until the double ends up being 0. however when putting in a double of value say .7904 i never exit the function as it keeps taking away digits which never end up being 0 as the resut of .7904 ends up being 7,903,999,988 and not 7,904,000,000.
How can i solve this problem?? Thanks =) ! oh and any other feed back on my code is WELCOME!
here's the code of my function:
/////////////////////// Numb_Digits() ////////////////////////////////////////////////////
enum{DECIMALS = 10, WHOLE_NUMBS = 20, ALL = 30};
template<typename T>
unsigned long int Numb_Digits(T numb, int scope)
{
unsigned long int length= 0;
switch(scope){
case DECIMALS: numb-= (int)numb; numb*=10000000000; // 10 bil (10 zeros)
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
case WHOLE_NUMBS: numb= (int)numb; numb*=10000000000;
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
case ALL: numb = numb; numb*=10000000000;
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
default: break;}
return length;
};
int main()
{
double test = 345.6457;
cout << Numb_Digits(test, ALL) << endl;
cout << Numb_Digits(test, DECIMALS) << endl;
cout << Numb_Digits(test, WHOLE_NUMBS) << endl;
return 0;
}
It's because of their binary representation, which is discussed in depth here:
http://en.wikipedia.org/wiki/IEEE_754-2008
Basically, when a number can't be represented as is, an approximation is used instead.
To compare floats for equality, check if their difference is lesser than an arbitrary precision.
The easy summary about floating point arithmetic :
http://floating-point-gui.de/
Read this and you'll see the light.
If you're more on the math side, Goldberg paper is always nice :
http://cr.yp.to/2005-590/goldberg.pdf
Long story short : real numbers are stored with a fixed, irregular precision, leading to non obvious behaviors. This is unrelated to the language but more a design choice of how to handle real numbers as a whole.
This is because C++ (like most other languages) can not store floating point numbers with infinte precision.
Floating points are stored like this:
sign * coefficient * 10^exponent if you're using base 10.
The problem is that both the coefficient and exponent are stored as finite integers.
This is a common problem with storing floating point in computer programs, you usually get a tiny rounding error.
The most common way of dealing with this is:
Store the number as a fraction (x/y)
Use a delta that allows small deviations (if abs(x-y) < delta)
Use a third party library such as GMP that can store floating point with perfect precision.
Regarding your question about counting decimals.
There is no way of dealing with this if you get a double as input. You cannot be sure that the user actually sent 1.819999999645634565360 and not 1.82.
Either you have to change your input or change the way your function works.
More info on floating point can be found here: http://en.wikipedia.org/wiki/Floating_point
This is because of the way the IEEE floating point standard is implemented, which will vary depending on operations. It is an approximation of precision. Never use logic of if(float == float), ever!
Float numbers are represented in the form Significant digits × baseexponent(IEEE 754). In your case, float 1.82 = 1 + 0.5 + 0.25 + 0.0625 + ...
Since only a limited digits could be stored, therefore there will be a round error if the float number cannot be represented as a terminating expansion in the relevant base (base 2 in the case).
You should always check relative differences with floating point numbers, not absolute values.
You need to read this, too.
Computers don't store floating point numbers exactly. To accomplish what you are doing, you could store the original input as a string, and count the number of characters.