Round decimal for a float number - c++

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

Related

Cutting numbers after the comma

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);
}

C++ significant figures

How can I do math involving significant figures in C++? I want this to work correct with measured data from chemistry and physics experiments. An example: 65 / 5 = 10. I would need to get rid of unneeded decimal places and replace some digits with 0s.
Thanks!
This should get you what you need:
std::cout.precision(x); // x would be the number of significant figures to output
This may not be the most efficient way, but you can create a custom sig fig data type.
class SigFigFloat
{
SigFigFloat(vector<short> digits, int decimalIndex, bool negative);
SigFigFloat operator+(const SigFigFloat &value);
SigFigFloat operator-(const SigFigFloat &value);
//etc...
}
It can be a lot of work, but if you implement this right, it can be a really flexible way to represent and do calculations with sig figs.
It is hard because significant figures are a decimal concept, and computers speak binary. You can use decimal number classes (I don't know of any), or use boost::interval, which is the closest to what you certainly want to achieve.
That depends on how you are displaying them. If you are using the printf-family, you set the precision (sprintf(buffer, "%.2f", myfloat)). If you are using ostreams, you call the precision function to set the number of decimal places. If you are looking for the more scientific method of sig figs, you'll have to write a custom function that determines the precision based on the current value of the float.
You can also:
#define SIGNIFICANT_DIGITS 3
const float SIGNIFICANT_DIGITS_PWR = powf(10.0f, SIGNIFICANT_DIGITS);
float f;
std::cin >> f;
int int_digits = (int)log10f(f) + 1;
if (int_digits > 1) {
float prod = SIGNIFICANT_DIGITS_PWR / powf(10.0f, int_digits);
f = (float)(int)(f * prod) / prod;
} else {
f = (float)((int)(f * SIGNIFICANT_DIGITS_PWR)) / SIGNIFICANT_DIGITS_PWR;
};
std::cout << f << '\n';
Output:
0.1234
> 0.123
12.34
> 12.3
1234
> 1230
here is a quick C++11 solution that worked for me:
int sig_figs = 3;
double number = 1562.654478;
std::cout << "original number:" << number << std::endl;
number = ([number](int number_of_sig_figs)->double{
std::stringstream lStream;
lStream << std::setprecision(number_of_sig_figs) << number;
return std::stod(lStream.str());
})(sig_figs);
std::cout << "rounded number:" << number << std::endl;
Well there are good math libraries in math.h
Also storing your figures in floats, doubles or long doubles will allow for more precise operations.
Floats offer 7 significant digits while doubles offer 16 significant digits.
source
Also when printing out usually people use _snprintf or printf and you can format those doubles, floats to the precision you want like:
Float Precision
printf("Value %8.2f", floatVariable);
This says you require a total
field of 8 characters, within the 8
characters the last 2 will hold the
decimal part.
_snprintf(buffer, sizeof(buffer), "Value %.2f", floatVariable);
The example above
requests the minimum field width and
the last two characters are to hold
the decimal part.

Maximum Width of a Printed Double in C++

I was wondering, how long in number of characters would the longest a double printed using fprintf be? My guess is wrong.
Thanks in advance.
Twelve would be a bit of an underestimate. On my machine, the following results in a 317 character long string:
#include <limits>
#include <cstdio>
#include <cstring>
int main()
{
double d = -std::numeric_limits<double>::max();
char str[2048] = "";
std::sprintf(str, "%f", d);
std::size_t length = std::strlen(str);
}
Using %e results in a 14 character long string.
Who knows. The Standard doesn't say how many digits of precision a double provides other than saying it (3.9.1.8) "provides at least as much precision as float," so you don't really know how many characters you'll need to sprintf an arbitrary value. Even if you did know how many digits your implementation provided, there's still the question of exponential formatting, etc.
But there's a MUCH bigger question here. Why the heck would you care? I'm guessing it's because you're trying to write something like this:
double d = ...;
int MAGIC_NUMBER = ...;
char buffer[MAGIC_NUMBER];
sprintf(buffer, "%f", d);
This is a bad way to do this, precisely because you don't know how big MAGIC_NUMBER should be. You can pick something that should be big enough, like 14 or 128k, but then the number you picked is arbitrary, not based on anything but a guess that it will be big enough. Numbers like MAGIC_NUMBER are, not suprisingly, called Magic Numbers. Stay away from them. They will make you cry one day.
Instead, there's a lot of ways to do this string formatting without having to care about buffer sizes, digits of precision, etc, that let you just get on with the buisness of programming. Streams is one:
#include <sstream>
double d = ...;
stringstream ss;
ss << d;
string s = ss.str();
cout << s;
...Boost.Format is another:
#include <boost\format\format.hpp>
double d = ... ;
string s = (boost::format("%1%") % d).str();
cout << s;
Its defined in limits:
std::cout << std::numeric_limits<double>::digits << "\n";
std::cout << std::numeric_limits<double>::digits10 << "\n";
Definition:
digits: number of digits (in radix base) in the mantissa
Equivalent to FLT_MANT_DIG, DBL_MANT_DIG or LDBL_MANT_DIG.
digits10: Number of digits (in decimal base) that can be represented without change.
Equivalent to FLT_DIG, DBL_DIG or LDBL_DIG for floating types.
See: http://www.cplusplus.com/reference/std/limits/numeric_limits/
Of course when you print stuff to a stream you can use the stream manipulators to limit the size of the output.
you can decide it by yourself..
double a=1.1111111111111111111111111111111111111111111111111;
printf("%1.15lf\n", a);
return 0;
./a.out
1.111111111111111
you can print more than 12 characters..
If your machine uses IEEE754 doubles (which is fairly widespread now), then the binary precision is 53 bits; The decimal equivalent is approximately 15.95 (calculated via logarithmic conversion), so you can usually rely on 15 decimal digits of precision.
Consult Double precision floating-point format for a brief discussion.
For a much more in-depth study, the canonical paper is What Every Computer Scientist Should Know About Floating-Point Arithmetic. It gets cited here whenever binary floating point discussions pop up, and is worth a weekend of careful reading.

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.