This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
When I used VS 2015 to debug the following code,
int main()
{
char thev[8] = "0.12345";
float fv = atof(thev);
printf("%f\n", fv);
return 0;
}
the value of fv in watch window is 0.12345004,
and printf is 0.123450, how to let fv=0.12345 in the run time?
There is similar post, here, but no answer there, can somebody help me?
And I pasted that code to my VS 2015,
int main()
{
const char *val = "73.31";
std::stringstream ss;
ss << val;
double doubleVal = 0.0f;
ss >> doubleVal;
}
the value doubleVal in watch window is 73.310000000000002
Replace the following code:
printf("%f\n", fv);
with:
printf("%.5f\n", fv);
Explaination:
we use a width (%.5f) to say that we want 5 digits (positions) reserved for the output.
The result is that 5 “space characters” are placed before printing the character. And the next character will be not printed.
Reference: https://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output
There is no exact representation in IEEE single precision for 0.12345. The closest two values on either side of it are 0.123450003564357757568359375 and 0.12344999611377716064453125. atof is picking the former, I think because it is closer to 0.12345 than the latter.
Related
This question already has answers here:
Convert char to int in C and C++
(14 answers)
Closed 2 years ago.
I am having trouble trying to converting time from 12 hour format to 24 hour format.
Note:- This is from an online test site and is filled with boilerplate code to work with the site, so I'm only going to post the part of the program where I am allowed to type.
string timeConversion(string s) {
/*
* Write your code here.
*/
int hours = ((int) s[0])*10+((int) s[1]);
char r[7];
//cout<< sizeof(s)<<"\n";
if(s[8]=='P')
{
hours=hours+12;
r[0]=(char) (hours/10);
r[1]=(char) (hours%10);
for (int i=2;i<8;i++)
{
r[i]=s[i];
}
}else
{
for(int i=0;i<8;i++)
{
r[i]=s[i];
}
}
return r;
}
Here is the input and outputs of test
Input(stdin):-
07:05:45PM
My output(stdout):-
6:05:45
Expected output:-
19:05:45
Now I test line 5 (i.e the line where i convert the hours section into an integer) in another compiler by itself and for some reason instead of properly converting its showing hours=534
Can you guys tell me what went wrong and how to fix it?
I found out what was going wrong with my code earlier. The reason why it didnt work is because c++ doesn't convert the numerical character into the actual numerical value, rather it converts it into the corresponding ascii value for which starts at 48 for "0" and ends at 57 for "9"
Statement to use for converting hours in the string and vice versa would be to
string -> int
int hours = (((int) s[0])%48)*10+(((int) s[1])%48);
or
int hours = (((int) s[0])-48)*10+(((int) s[1])-48);
int -> string
r[0]=(char) ((hours/10)+48);
r[1]=(char) ((hours%10)+48);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am passing a string variable (std::string) and iterating through the string character by character. Whenever I run into a decimal, I want to combine the previous position on the string (i.e 2) and the next position in the string (i.e 5) into a double. So how would I go about making the char 2, char . , char 5 into one whole value (2.5)?
std::double x;
std::string varibleName = "4 5 7 2.5";
for (int i = 0; i < variableName.length(); i++) // iterates through variableName
{
if (variableName[i] == '.'){ // if the current position of the iteration is a decimal, I want to grab the char before the decimal and the char after the decimal so I can combine all three positions of the string making it 2.5 and not 25.
}
}
Well, you are wildly overthinking it. The C++ library provides std::stof, std::stod, std::stold that does exactly what you want. Convert a string like "2.5" to a float, double or long double, e.g.
#include <iostream>
int main (void) {
std::string s = "2.5";
double d = std::stod(s);
std::cout << d << "\n";
}
Example Use/Output
$ ./bin/stodex
2.5
Look things over and let me know if you have further overthinking questions.
Note that giving an example, code snips, and error logs make troubleshooting a lot easier :)
It sound like you have some input like "2.1" and need to convert it to a double like 2.1?
If that is the case you can use the <cstdlib> atof function.
Example:
/* atof example: sine calculator */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atof */
#include <math.h> /* sin */
int main ()
{
double n;
char buffer[256];
printf ("Enter degrees: ");
fgets (buffer,256,stdin);
n = atof (buffer);
printf ("You entered %s which is a double like %f\n" , buffer, n);
return 0;
}
This question already has answers here:
How can I assign hex string to a char[] variable?
(7 answers)
Closed 8 years ago.
I get a string which is given as an argument to a function like e.g. 00112233445566778899aabbccddeeff and I need to make an unsigned char array of it which looks like this:
unsigned char array[16]= {0x00 ,0x11 ,0x22 ,0x33 ,0x44 ,0x55 ,0x66 ,0x77 ,0x88 ,0x99 ,0xaa ,0xbb ,0xcc ,0xdd ,0xee ,0xff};
I have no idea how to do it, tried some things with strcpy and thought about hex but this works only with << or >> as I know so I don't think I know how to apply it here. Anyone could help please?
It seems you need to convert each digit received to a nibble and to combine two nibbles into a byte. The conversion from digit to nibble can be done using a look-up or using conditional logic for digits and letters. The combination is a bitwise shift and a bitwise or.
I could write the code but I've somewhat outgrown assignments, not to mention that my version is unlikely to be a viable solution anyway.
You could do this with a combination of istringstream and std::hex.
example
#include <iostream>
#include <sstream>
int main() {
std::string myStr = "1122AA010A";
std::stringstream ss;
int n;
for(int i = 0; i<myStr.length(); ) {
std::istringstream(myStr.substr(i,2))>>std::hex>>n;
ss<<(char)n;
i += 2;
}
std::string result = ss.str();
std::cout<<"\n"<<result<<"\n";
return 0;
}
I am looking for a library function to convert floating point numbers to strings, and back again, in C++. The properties I want are that str2num(num2str(x)) == x and that num2str(str2num(x)) == x (as far as possible). The general property is that num2str should represent the simplest rational number that when rounded to the nearest representable floating pointer number gives you back the original number.
So far I've tried boost::lexical_cast:
double d = 1.34;
string_t s = boost::lexical_cast<string_t>(d);
printf("%s\n", s.c_str());
// outputs 1.3400000000000001
And I've tried std::ostringstream, which seems to work for most values if I do stream.precision(16). However, at precision 15 or 17 it either truncates or gives ugly output for things like 1.34. I don't think that precision 16 is guaranteed to have any particular properties I require, and suspect it breaks down for many numbers.
Is there a C++ library that has such a conversion? Or is such a conversion function already buried somewhere in the standard libraries/boost.
The reason for wanting these functions is to save floating point values to CSV files, and then read them correctly. In addition, I'd like the CSV files to contain simple numbers as far as possible so they can be consumed by humans.
I know that the Haskell read/show functions already have the properties I am after, as do the BSD C libraries. The standard references for string<->double conversions is a pair of papers from PLDI 1990:
How to read floating point numbers accurately, Will Klinger
How to print floating point numbers accurately, Guy Steele et al
Any C++ library/function based on these would be suitable.
EDIT: I am fully aware that floating point numbers are inexact representations of decimal numbers, and that 1.34==1.3400000000000001. However, as the papers referenced above point out, that's no excuse for choosing to display as "1.3400000000000001"
EDIT2: This paper explains exactly what I'm looking for: http://drj11.wordpress.com/2007/07/03/python-poor-printing-of-floating-point/
I am still unable to find a library that supplies the necessary code, but I did find some code that does work:
http://svn.python.org/view/python/branches/py3k/Python/dtoa.c?view=markup
By supplying a fairly small number of defines it's easy to abstract away the Python integration. This code does indeed meet all the properties I outline.
I think this does what you want, in combination with the standard library's strtod():
#include <stdio.h>
#include <stdlib.h>
int dtostr(char* buf, size_t size, double n)
{
int prec = 15;
while(1)
{
int ret = snprintf(buf, size, "%.*g", prec, n);
if(prec++ == 18 || n == strtod(buf, 0)) return ret;
}
}
A simple demo, which doesn't bother to check input words for trailing garbage:
int main(int argc, char** argv)
{
int i;
for(i = 1; i < argc; i++)
{
char buf[32];
dtostr(buf, sizeof(buf), strtod(argv[i], 0));
printf("%s\n", buf);
}
return 0;
}
Some example inputs:
% ./a.out 0.1 1234567890.1234567890 17 1e99 1.34 0.000001 0 -0 +INF NaN
0.1
1234567890.1234567
17
1e+99
1.34
1e-06
0
-0
inf
nan
I imagine your C library needs to conform to some sufficiently recent version of the standard in order to guarantee correct rounding.
I'm not sure I chose the ideal bounds on prec, but I imagine they must be close. Maybe they could be tighter? Similarly I think 32 characters for buf are always sufficient but never necessary. Obviously this all assumes 64-bit IEEE doubles. Might be worth checking that assumption with some kind of clever preprocessor directive -- sizeof(double) == 8 would be a good start.
The exponent is a bit messy, but it wouldn't be difficult to fix after breaking out of the loop but before returning, perhaps using memmove() or suchlike to shift things leftwards. I'm pretty sure there's guaranteed to be at most one + and at most one leading 0, and I don't think they can even both occur at the same time for prec >= 10 or so.
Likewise if you'd rather ignore signed zero, as Javascript does, you can easily handle it up front, e.g.:
if(n == 0) return snprintf(buf, size, "0");
I'd be curious to see a detailed comparison with that 3000-line monstrosity you dug up in the Python codebase. Presumably the short version is slower, or less correct, or something? It would be disappointing if it were neither....
The reason for wanting these functions is to save floating point values to CSV files, and then read them correctly. In addition, I'd like the CSV files to contain simple numbers as far as possible so they can be consumed by humans.
You cannot have conversion double → string → double and in the same time having the string human readable.
You need to need to choose between an exact conversion and a human readable string. This is the definition of max_digits10 and digits10:
difference explained by stackoverflow
digits10
max_digits10
Here is an implementation of num2str and str2num with two different contexts from_double (conversion double → string → double) and from_string (conversion string → double → string):
#include <iostream>
#include <limits>
#include <iomanip>
#include <sstream>
namespace from_double
{
std::string num2str(double d)
{
std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::max_digits10) << d;
return ss.str();
}
double str2num(const std::string& s)
{
double d;
std::stringstream ss(s);
ss >> std::setprecision(std::numeric_limits<double>::max_digits10) >> d;
return d;
}
}
namespace from_string
{
std::string num2str(double d)
{
std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::digits10) << d;
return ss.str();
}
double str2num(const std::string& s)
{
double d;
std::stringstream ss(s);
ss >> std::setprecision(std::numeric_limits<double>::digits10) >> d;
return d;
}
}
int main()
{
double d = 1.34;
if (from_double::str2num(from_double::num2str(d)) == d)
std::cout << "Good for double -> string -> double" << std::endl;
else
std::cout << "Bad for double -> string -> double" << std::endl;
std::string s = "1.34";
if (from_string::num2str(from_string::str2num(s)) == s)
std::cout << "Good for string -> double -> string" << std::endl;
else
std::cout << "Bad for string -> double -> string" << std::endl;
return 0;
}
Actually I think you'll find that 1.34 IS 1.3400000000000001. Floating point numbers are not precise. You can't get around this. 1.34f is 1.34000000333786011 for example.
As stated by others. Floating-point numbers are not that accurate its an artifact on how they store the value.
What you are really looking for is a Decimal number representation.
Basically this uses an integer to store the number and has a specific accuracy after the decimal point.
A quick Google got this:
http://www.codeproject.com/KB/mcpp/decimalclass.aspx
I am trying to manipulate a string in C++. I am working with an Arduino board so I am limited on what I can use. I am also still learning C++ (Sorry for any stupid questions)
Here is what I need to do:
I need to send miles per hour to a 7 segment display. So if I have a number such as 17.812345, I need to display 17.8 to the 7 segment display. What seems to be most efficient way is to first multiply by 10 (This is to shift the decimal point right one place), then cast 178.12345 to an int (to chop decimal points off). The part I am stuck on is how to break apart 178. In Python I could slice the string, but I can't find anything on how to do this in C++ (or at least, I can't find the right terms to search for)
There are four 7 segment displays and a 7 segment display controller. It will measure up to tenths of a mile per hour. Thank you very much for an assistance and information you can provide me.
It would probably be easiest to not convert it to a string, but just use arithmetic to separate the digits, i.e.
float speed = 17.812345;
int display_speed = speed * 10 + 0.5; // round to nearest 0.1 == 178
int digits[4];
digits[3] = display_speed % 10; // == 8
digits[2] = (display_speed / 10) % 10; // == 7
digits[1] = (display_speed / 100) % 10; // == 1
digits[0] = (display_speed / 1000) % 10; // == 0
and, as pointed out in the comments, if you need the ASCII value for each digit:
char ascii_digits[4];
ascii_digits[0] = digits[0] + '0';
ascii_digits[1] = digits[1] + '0';
ascii_digits[2] = digits[2] + '0';
ascii_digits[3] = digits[3] + '0';
This a way you can do it in C++ without modulus math (either way seems fine to me):
#include "math.h"
#include <stdio.h>
#include <iostream.h>
int main( ) {
float value = 3.1415;
char buf[16];
value = floor( value * 10.0f ) / 10.0f;
sprintf( buf, "%0.1f", value );
std::cout << "Value: " << value << std::endl;
return 0;
}
If you actually want to be processing this stuff as strings, I would recommend looking into stringstream. It can be used much the same as any other stream, such as cin and cout, except instead of sending all output to the console you get an actual string out of the deal.
This will work with standard C++. Don't know much about Arduino, but some quick googling suggests it won't support stringstreams.
A quick example:
#include <sstream> // include this for stringstreams
#include <iostream>
#include <string>
using namespace std; // stringstream, like almost everything, is in std
string stringifyFloat(float f) {
stringstream ss;
ss.precision(1); // set decimal precision to one digit.
ss << fixed; // use fixed rather than scientific notation.
ss << f; // read in the value of f
return ss.str(); // return the string associated with the stream.
}
int main() {
cout << stringifyFloat(17.812345) << endl; // 17.8
return 0;
}
You can use a function such as this toString and work your way up from there, like you would in Python, or just use modulo 10,100,1000,etc to get it as numbers. I think manipulating it as a string might be easier for you, but its up to you.
You could also use boost::lexical_cast, but it will probably be hard to get boost working in an embedded system like yours.
A good idea would be to implement a stream for the display. That way the C++ stream syntax could be used and the rest of the application would remain generic. Although this may be overkill for an embedded system.
If you still want to use std::string you may want to use a reverse iterator. This way you can start at the right most digit (in the string) and work towards the left, one character at a time.
If you have access to the run-time library code, you could set up a C language I/O for the display. This is easier to implement than a C++ stream. You could then use fprint, fputs to write to the display. I implemented a debug port in this method, and it was easier for the rest of the developers to use.