Cutting numbers after the comma - c++

I have a trouble.
I'm trying to convert double number like this 4.66667 to 4.6. I know that it can be done with cout.precision function, but I need to convert it, not print.
The whole idea is that I need to make some operations like 8/5, and then cut numbers after the comma, leave just the 4.6, put it in the new variable and request from the user to put exactly 4.6.
If you have any idea, thank you very much.

You can use floor with a trick :
float rounded_down = floorf(val * 10) / 10;
(10 is to keep 1 decimal, 100 to keep two...)

I have a function that I wrote for this. The function takes doubles but you change change it if you need if you are using something bigger than a double.
double floorRound(double val, int places)
{
return std::floor(val * std::pow(10.0, places)) / std::pow(10.0, places);
}

Related

Round decimal for a float number

in VC++ I have a float number say 1.32544354353
i.e float num=1.32544354353;
I want only first 1 digit after point. i.e 1.3 (not 1.300000000).
How can I get this?
Please help me...
If their is a solution in Cocos2dx thats better(I want this in my cocos2d-x game)
The answer depends on what type do you want the result to be.
If you want to obtain the result as float, then this is impossible. From float's point of view, 1.3 and 1.300000000 are exactly the same values and you can not have a float that holds 1.3, not 1.300000000. What you can do here is to drop extra digits by using, e.g., (int)(val*10)/10.0. (However, the float number precision problems will not make the results exactly 1.3, it will be something line 1.2999999982 or 1.3000000029 with some random digits at the end.)
If you want a string (meaning a string in general) representation, then you can gen a string "1.3". To obtain this, use precision specifiers
such as "%.1f" or std::setprecision(1).
Try something like
float val=1.32544;
float num=(float)(((int)(val*10))/10.0);
but beware of the overflow.
Try this:
#include <math.h>
float x= 1.32544354353;
float f = roundf(x* 10) / 10;
If you just want to print it then you can simply use the format specifier like this:
("%.1f", 1.32544354353);
or
double d = 1.32544354353;
std::cout << std::fixed << std::setprecision(1) << d << std::endl;
first thing that comes in my mind is that you can multiplay this by 10 (you will get 13) then cast this to int (so no more numbers after dot) and then divide this by 10 to float (you will get 1.3)
char str[50];
sprintf(str, "%.1f",1.324567);
now str have a string 1.3

How can I find the amount of numbers in double?

Let's say I have an input 1.251564.
How can I find how many elements are after "." to have an output as follows:
int numFloating;
// code to go here that leads to
// numFloating == 6
p.s. Sorry for not providing any code, I just have no idea how that should be implemented :(
Thanks for your answers!
Let us consider your number, 1.251564. When you store this in a double, it is stored in the binary IEEE754 format. And you might find that the number is not representable. So, let us check for this number. The closest representable double is:
1.25156 39999 99999 89880 45035 73046 53152 82344 81811 52343 75
This probably comes as something of a surprise to you. There are 52 decimal digits following the decimal point.
The lesson that you need to take away from this is that if you want to ask questions about decimal representations, you need to use a decimal data type rather than double. Once you can actually represent the value exactly, then you will be able to reason about it in a manner that matches your expectations.
Simplest way would be to store it in string.
std::string str("1.1234");
size_t length = str.length();
size_t found = str.find('.', 0 );
size_t count = length-found-1;
int finallyGotTheCount = static_cast<int>(count);
This won't end up well. The problem is that sometimes there are float errors when representing numbers in binary (which is what your computer does).
For example, when adding 1 / 3 + 1 / 3 + 1 / 3 you might get 0.999999... and the number of decimal places varies greatly.
ravi already provided a good way to calculate it, so I'll provide a different one:
double number = 0; // should be equal to the number you want to check
int numFloating = 0;
while ((double)(int)number != number){
number *= 10;
numFloating++;
}
number is a double variable that holds the number you want to check for decimal places.
If you have a fractional number. Lets say .1234
Repeatedly multiply by 10 and throw away the integer portion of the number until you get zero. The number of steps will be the number of decimals. e.g:
.1234 * 10 = 1.234
.234 * 10 = 2.34
.34 * 10 = 3.4
.4 * 10 = 4.0
Problems will however occur when you have a number that is "floating" like 1.199999999.
int numFloating = 0;
double orgin = 1.251564;
double value = orgin - floor(orgin);
while(value == 0)
{
value *= 10;
value = value - floor(value);
numFloating ++;
}
By using this code sometimes answer is wrong. exp: zero in floating point is equal to (2^31)-1.
Obviously output depends on how it realy stored.

Truncating double without rounding in C

Lets consider we have a double R = 99.999999; (which may be obtained by a result of some other computation),now the desired output is 99.99
I tried using printf("%.2lf",R); but it's rounding off the value.How to get the desired output ? (preferably using printf)
#include <math.h>
...
printf("%.2f", floor(100 * R) / 100);
All you have to do is subtract .005 from the number and magically printf will behave as you wish: always round down.
sprintf it into a buffer, and then put the NUL char two bytes past the '.'
Then printf your final string using the intermediate one.
If you have it, use fmod() to chop the tail of the double:
double rounded = R - fmod(R, 0.01);
// Now just print rounded with what you were using before
This has the advantage of working the same if R is positive or negative.
What about using double trunc(double) from GLibC?
Can you multiply by 100 and then truncate to an integer? Then you could format the result like one would with dollars and cents. Simply dividing by 100 might land you back at square one due to floating-point representation issues.
Another solution, using casts:
...
printf("%.2lf", (double) ((int) (R * 100)) / 100);
Another way, truly sign agnostic:
printf("%d.%d\n", (int) r ,abs((int)(r*100) % 100));

C/C++ rounding up decimals with a certain precision, efficiently

I'm trying to optimize the following. The code bellow does this :
If a = 0.775 and I need precision 2 dp then a => 0.78
Basically, if the last digit is 5, it rounds upwards the next digit, otherwise it doesn't.
My problem was that 0.45 doesnt round to 0.5 with 1 decimalpoint, as the value is saved as 0.44999999343.... and setprecision rounds it to 0.4.
Thats why setprecision is forced to be higher setprecision(p+10) and then if it really ends in a 5, add the small amount in order to round up correctly.
Once done, it compares a with string b and returns the result. The problem is, this function is called a few billion times, making the program craw. Any better ideas on how to rewrite / optimize this and what functions in the code are so heavy on the machine?
bool match(double a,string b,int p) { //p = precision no greater than 7dp
double t[] = {0.2, 0.02, 0.002, 0.0002, 0.00002, 0.000002, 0.0000002, 0.00000002};
stringstream buff;
string temp;
buff << setprecision(p+10) << setiosflags(ios_base::fixed) << a; // 10 decimal precision
buff >> temp;
if(temp[temp.size()-10] == '5') a += t[p]; // help to round upwards
ostringstream test;
test << setprecision(p) << setiosflags(ios_base::fixed) << a;
temp = test.str();
if(b.compare(temp) == 0) return true;
return false;
}
I wrote an integer square root subroutine with nothing more than a couple dozen lines of ASM, with no API calls whatsoever - and it still could only do about 50 million SqRoots/second (this was about five years ago ...).
The point I'm making is that if you're going for billions of calls, even today's technology is going to choke.
But if you really want to make an effort to speed it up, remove as many API usages as humanly possible. This may require you to perform API tasks manually, instead of letting the libraries do it for you. Specifically, remove any type of stream operation. Those are slower than dirt in this context. You may really have to improvise there.
The only thing left to do after that is to replace as many lines of C++ as you can with custom ASM - but you'll have to be a perfectionist about it. Make sure you are taking full advantage of every CPU cycle and register - as well as every byte of CPU cache and stack space.
You may consider using integer values instead of floating-points, as these are far more ASM-friendly and much more efficient. You'd have to multiply the number by 10^7 (or 10^p, depending on how you decide to form your logic) to move the decimal all the way over to the right. Then you could safely convert the floating-point into a basic integer.
You'll have to rely on the computer hardware to do the rest.
<--Microsoft Specific-->
I'll also add that C++ identifiers (including static ones, as Donnie DeBoer mentioned) are directly accessible from ASM blocks nested into your C++ code. This makes inline ASM a breeze.
<--End Microsoft Specific-->
Depending on what you want the numbers for, you might want to use fixed point numbers instead of floating point. A quick search turns up this.
I think you can just add 0.005 for precision to hundredths, 0.0005 for thousands, etc. snprintf the result with something like "%1.2f" (hundredths, 1.3f thousandths, etc.) and compare the strings. You should be able to table-ize or parameterize this logic.
You could save some major cycles in your posted code by just making that double t[] static, so that it's not allocating it over and over.
Try this instead:
#include <cmath>
double setprecision(double x, int prec) {
return
ceil( x * pow(10,(double)prec) - .4999999999999)
/ pow(10,(double)prec);
}
It's probably faster. Maybe try inlining it as well, but that might hurt if it doesn't help.
Example of how it works:
2.345* 100 (10 to the 2nd power) = 234.5
234.5 - .4999999999999 = 234.0000000000001
ceil( 234.0000000000001 ) = 235
235 / 100 (10 to the 2nd power) = 2.35
The .4999999999999 was chosen because of the precision for a c++ double on a 32 bit system. If you're on a 64 bit platform you'll probably need more nines. If you increase the nines further on a 32 bit system it overflows and rounds down instead of up, i. e. 234.00000000000001 gets truncated to 234 in a double in (my) 32 bit environment.
Using floating point (an inexact representation) means you've lost some information about the true number. You can't simply "fix" the value stored in the double by adding a fudge value. That might fix certain cases (like .45), but it will break other cases. You'll end up rounding up numbers that should have been rounded down.
Here's a related article:
http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
I'm taking at guess at what you really mean to do. I suspect you're trying to see if a string contains a decimal representation of a double to some precision. Perhaps it's an arithmetic quiz program and you're trying to see if the user's response is "close enough" to the real answer. If that's the case, then it may be simpler to convert the string to a double and see if the absolute value of the difference between the two doubles is within some tolerance.
double string_to_double(const std::string &s)
{
std::stringstream buffer(s);
double d = 0.0;
buffer >> d;
return d;
}
bool match(const std::string &guess, double answer, int precision)
{
const static double thresh[] = { 0.5, 0.05, 0.005, 0.0005, /* etc. */ };
const double g = string_to_double(guess);
const double delta = g - answer;
return -thresh[precision] < delta && delta <= thresh[precision];
}
Another possibility is to round the answer first (while it's still numeric) BEFORE converting it to a string.
bool match2(const std::string &guess, double answer, int precision)
{
const static double thresh[] = {0.5, 0.05, 0.005, 0.0005, /* etc. */ };
const double rounded = answer + thresh[precision];
std::stringstream buffer;
buffer << std::setprecision(precision) << rounded;
return guess == buffer.str();
}
Both of these solutions should be faster than your sample code, but I'm not sure if they do what you really want.
As far as i see you are checking if a rounded on p points is equal b.
Insted of changing a to string, make other way and change string to double
- (just multiplications and addion or only additoins using small table)
- then substract both numbers and check if substraction is in proper range (if p==1 => abs(p-a) < 0.05)
Old time developers trick from the dark ages of Pounds, Shilling and pence in the old country.
The trick was to store the value as a whole number fo half-pennys. (Or whatever your smallest unit is). Then all your subsequent arithmatic is straightforward integer arithimatic and rounding etc will take care of itself.
So in your case you store your data in units of 200ths of whatever you are counting,
do simple integer calculations on these values and divide by 200 into a float varaible whenever you want to display the result.
I beleive Boost does a "BigDecimal" library these days, but, your requirement for run time speed would probably exclude this otherwise excellent solution.

Extracting individual digits from a float

I have been banging my head on this one all day. The C++ project I am currently working on has a requirement to display an editable value. The currently selected digit displays the incremented value above and decremented value below for said digit. It is useful to be able to reference the editable value as both a number and collection of digits. What would be awesome is if there was some indexable form of a floating point number, but I have been unable to find such a solution. I am throwing this question out there to see if there is something obvious I am missing or if I should just roll my own.
Thanks for the advice! I was hoping for a solution that wouldn't convert from float -> string -> int, but I think that is the best way to get away from floating point quantization issues. I ended up going with boost::format and just referencing the individual characters of the string. I can't see that being a huge performance difference compared to using combinations of modf and fmod to attempt to get a digit out of a float (It probably does just that behind the scenes, only more robustly than my implementation).
Internal representation of the float point numbers aren't like was you see. You can only cast to a stirng.
To cast, do this:
char string[99];
sprintf(string,"%f",floatValue);
Or see this : http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.1
The wikipedia article can explain more on the representation: http://en.wikipedia.org/wiki/Floating_point
Oh, there are many ways to convert to a string. (Though I do prefer snprintf() myself.)
Or you could convert to an int and pull the digits out with modulus and integer-division. You can count the number of digits with log{base10}.
(Remember: log{baseA}_X / log{baseA}_B = log{baseB}_X.)
Example:
#define SHOW(X) cout << # X " = " << (X) << endl
int
main()
{
double d = 1234.567;
SHOW( (int(d)%10000) / 1000 );
SHOW( (int(d)%1000) / 100 );
SHOW( (int(d)%100) / 10 );
SHOW( (int(d)%10) );
SHOW( (int(d*10) % 10) );
SHOW( (int(d*100) % 10) );
SHOW( (int(d*1000)% 10) );
SHOW( log(d)/log(10) );
}
Though you ought to use static_cast...
Watch out for exponential notation. With a very big or very small numbers, you may have a problem.
Floating point numbers also have round off issues that may cause you some grief. (It's the same reason why we don't use operator== between two doubles. Or why you can't rely on a*b == b*a. Depending on the exact values of a & b, they may differ very slightly out around 10^-25.)
You can cast between string and float only by using boost::lexical_cast. However, you can't directly index the float form - it's internally not stored as decimal digits. This is probably not that much of an issue. For your UI, you will most likely keep a string form of the number anyway, with conversions to and from float in the getter/setter.