I want to ask how to remove trailing zeros after decimal point?
I've read lots of topics about it but I don't understand them clearly. Could you show me any easy understanding ways ?
For example 12.50 to 12.5, but the actual output is 12.50
This is one thing that IMHO is overly complicated in C++. Anyway, you need to specify the desired format by setting properties on the output stream. For convenience a number of manipulators are defined.
In this case, you need to set fixed representation and set precision to 2 to obtain the rounding to 2 decimals after the point using the corresponding manipulators, see below (notice that setprecisioncauses rounding to the desired precision). The tricky part is then to remove trailing zeroes. As far as I know C++ does not support this out of the box, so you have to do some string manipulation.
To be able to do this, we will first "print" the value to a string and then manipulate that string before printing it:
#include <iostream>
#include <iomanip>
int main()
{
double value = 12.498;
// Print value to a string
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << value;
std::string str = ss.str();
// Ensure that there is a decimal point somewhere (there should be)
if(str.find('.') != std::string::npos)
{
// Remove trailing zeroes
str = str.substr(0, str.find_last_not_of('0')+1);
// If the decimal point is now the last character, remove that as well
if(str.find('.') == str.size()-1)
{
str = str.substr(0, str.size()-1);
}
}
std::cout << str << std::endl;
}
For C++ check this How to output float to cout without scientific notation or trailing zeros?
using printf() you may use following method to do this,
int main()
{
double value = 12.500;
printf("%.6g", value ); // 12.5 with 6 digit precision
printf("%.6g", 32.1234); // 32.1234
printf("%.6g", 32.12300000); // 32.123
}
std::string example = std::to_string(10.500f);
while (example[example.size() - 1] == '0' || example[example.size() - 1] == '.')
example.resize(example.size() - 1);
Just use 'printf' function.
printf("%.8g",8.230400); will print '8.2304'
float value =4.5300;
printf ("%.8g",value);
will return 4.53.
Try this code . It is quite simple.
I was stumped by this for a while and didn't want to convert to a string to get the job done, so I came up with this:
float value = 1.00;
char buffer[10];
sprintf(buffer, "%.2f", value);
int lastZero = strlen(buffer);
for (int i = strlen(buffer) - 1; i >= 0; i--)
{
if (buffer[i] == '\0' || buffer[i]=='0' || buffer[i]=='.')
lastZero = i;
else
break;
}
if (lastZero==0)
lastZero++;
char newValue[lastZero + 1];
strncpy(newValue, buffer, lastZero);
newValue[lastZero] = '\0';
newValue = 1
you can round-off the value to 2 digits after decimal,
x = floor((x * 100) + 0.5)/100;
and then print using printf to truncate any trailing zeros..
printf("%g", x);
example:
double x = 25.528;
x = floor((x * 100) + 0.5)/100;
printf("%g", x);
output: 25.53
Related
I want to convert a MPFR floating point number into a string.
If I run my program the string is generated but without the "." in the number. How can I do it right?
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <mpreal.h>
using mpfr::mpreal;
using std::cout;
using std::endl;
int main (int ac, char *av[])
{
char data[255];
mpreal x = 42.0, y = 3.14159265358979323846, res = 0.0;
mp_exp_t exponent = 10;
// string data_str[256];
int precision = 50;
res = x * y;
cout.precision(100);
cout << res;
cout << "\n";
// if (mpfr_snprintf (data, 254, "%.20Ff", res.mpfr_srcptr()) < 0)
/*
if (mpfr_snprintf (data, 254, "%.20Ff", res.mpfr_srcptr()) < 0)
{
cout << "gmp_prints_float: error saving string!\n";
}
*/
mpfr_get_str ((char *) &data, &exponent, 10, precision, res.mpfr_srcptr(), GMP_RNDN);
cout << data;
cout << "\n";
mpfr_free_cache ();
}
131.946891450771317977341823279857635498046875
13194689145077131797734182327985763549804687500000
There is no decimal point in the string output!
From the documentation
The generated string is a fraction, with an implicit radix point immediately to the left of the first digit. For example, the number -3.1416 would be returned as "-31416" in the string and 1 written at expptr.
It is up to you to generate a human-readable representation fron the string and the exponent.
An alternative would be to use mpfr_sprintf.
MPFR's mpfr_get_str function is copied on GMP's mpf_get_str function, explaining why it has been chosen not to write a decimal point. There are two solutions to have a decimal point:
Use mpfr_sprintf (or some variant), as suggested in this answer. I would recommend this solution (perhaps unless you want to ignore the locales), as it is the most flexible in the output format and does not need a correction.
If you just want the significand with an explicit decimal point, use mpfr_get_str, but with a pointer buffer+1 instead of buffer. Then, do something like (disregarding the locales)
int neg = buffer[1] == '-';
if (neg)
buffer[0] = '-';
buffer[neg] = '.';
after filtering the special cases (NaN and infinities).
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 6 years ago.
Improve this question
I have tried to get the number of digit from double value but it is not working properly. I have tried this:
int main()
{
double value = 123456.05;
std::cout<<"number of digit::"<<((int)std::log10(value ) + 1);
}
output::
number of digit::6
How to get exact number of digits? Expected result is 9.
Assuming that you only need this to work for double literals, the following will work.
EDIT: Added an equivalent function that works for a subset of doubles. It uses exhaustive search for all reasonable ways to display a double in decimal, there is probably some way to make it more efficient if you need this function to really scream.
#include <iostream>
#include <string.h>
#include <assert.h>
#include <cmath>
struct double_literal {
const char* string_value;
double double_value;
size_t num_digits;
};
#define DOUBLE_LITERAL(x) {#x, x, strlen(#x)};
size_t num_digits(double value){
//Double gives around 15 accurate digits usually.
//Disregarding exponential notation, there are hence only 15 reasonable
//ways to display value, ranging from 15 places in front of the decimal
//to 15 behind. Figure out which of these is best in terms of error,
//and then at the end print out how many digits are needed to display
//the number by removing unecessary zeros.
//Routine currently only handles values within these bounds
//If your value is outside, can scale it with a power of ten before
//using. Special cases for zero and negative values can also be added.
double window_stop = std::pow(10.0, 15);
double window_start = 1 + std::pow(10.0, -15);
assert(value < window_stop);
assert(value > window_start);
size_t best_window = 0;
double best_error = INFINITY;
double pow_ten_window = 1;
for(size_t window = 0; window <= 15; window++, pow_ten_window *= 10){
double rounded = fmod(
std::round(value * pow_ten_window),
window_stop
) / pow_ten_window;
double error = std::abs(rounded - value);
if (error < best_error){
best_error = error;
best_window = window;
}
}
unsigned long long best_rounding = std::llround(
fmod(
value * std::pow(10.0, best_window),
window_stop
)
);
size_t best_digits = std::llround(std::log10(best_rounding) + 1);
//Representation has an integer part => just figure out if we
//need a decimal point
if (best_window > 0){
best_digits++;
}
std::cout << best_window << std::endl;
return best_digits;
}
int main(int argc, char** argv){
struct double_literal literal DOUBLE_LITERAL(123456.05);
std::cout << "number of digit::" << literal.num_digits << std::endl;
//As a function
std::cout << "numbr of digit::" << num_digits(literal.double_value);
}
Using the literal, you can get the value of the literal in multiple forms later in the code.
The function works on non-literals as well, but only for a restricted subset of doubles. See the comments for how to generalize it for the rest.
You can convert the double value to string:
double value = 123456.05;
std::string s = std::to_string(value);
After it you need to remove trailing zeroez (because it is possible that s == "123456.050000" now):
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
Than get a number of characters of this string:
std::cout<<"number of digit::"<< s.length();
(In this case you will process "." as digit)
So, the program below returns expected result:
number of digit::9
But this is not perfect for integer values, because "123" will be represented as "123." (one more character at the end). So, for integer values it is better to remove trailing "." before getting of the length:
void print_nb_digits(double value) {
std::string s = std::to_string(value);
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
if (!s.empty() && !std::isdigit(s.back()))
s.pop_back();
std::cout<<"number of digit::"<< s.length();
}
double value = 123456.05;
print_nb_digits(value);
In this case the program returns correct result for value = 123456 too:
number of digit::6
I have a programming assignment where I need to encrypt a 4 digit int, input by user. I have split the int into four separate values and the encrypt and decrypt functions work. My problem is when I put the four separate ints back together, some numbers encrypt to zero (eg. in:1234 out:0189) and I want to store the output into an int for use with other functions.
Right now I have a half-baked solution that prints 0 first if the first int is 0.
void joinInt(){
if(int1 == 0) {cout << 0;}
joined = int1 * 1000;
joined += int2 * 100;
joined += int3 * 10;
joined += int4;
cout << joined << endl;
}
My goal is to return joined (with the leading zero) rather than just print it within the function.
Do this:
#include <iomanip>
#include <iostream>
std::cout << std::setfill('0') << std::setw(4) << joined << std::endl;
An int contains a number. It does not contain any particular representation information, like whether it was input from text containing one leading zero or two, or whether it was written in hexadecimal, octal, or chicken scratches, or even if it was computed from adding a bunch of numbers. It is just a value.
If you want to display an int with leading zeros, then you have to explicitly convert it that way:
char buf [20];
snprintf (buf, sizeof buf, "%04d", myint); // output base 10, + leading zeros
// for a field width of 4
An int basically stores leading zeros. The problem that you are running into is that you are not printing the leading zeros that are there.
Another, different approach is to create a function that will accept the four int values along with a string and to then return a string with the numbers.
With this approach you have a helper function with very good cohesion, no side effects, reusable where you need something similar to be done.
For instance:
char *joinedIntString (char *pBuff, int int1, int int2, int int3, int int4)
{
pBuff[0] = (int1 % 10) + '0';
pBuff[1] = (int2 % 10) + '0';
pBuff[2] = (int3 % 10) + '0';
pBuff[3] = (int4 % 10) + '0';
pBuff[4] = 0; // end of string needed.
return pBuff;
}
Then in the place where you need to print the value you can just call the function with the arguments and the provided character buffer and then just print the character buffer.
With this approach if you have some unreasonable numbers that end up have more than one leading zero, you will get all of the zeros.
Or you may want to have a function that combines the four ints into a single int and then another function that will print the combined int with leading zeros.
int createJoinedInt (int int1, int int2, int int3, int int4)
{
return (int1 % 10) * 1000 + (int2 % 10) * 100 + (int 3 % 10) * 10 + (int4 % 10);
}
char *joinedIntString (char *pBuff, int joinedInt)
{
pBuff[0] = ((joinedInt / 1000) % 10) + '0';
pBuff[1] = ((joinedInt / 100) % 10) + '0';
pBuff[2] = ((joinedInt / 10) % 10) + '0';
pBuff[3] = (joinedInt % 10) + '0';
pBuff[4] = 0; // end of string needed.
return pBuff;
}
This should do the trick.
cout << setw(4) << setfill('0') << joined << endl;
In order to use these manipulators, you'll need to:
#include <iomanip>
C++ stores int as a binary number. However all IO is as string. So, to display an int there must be a conversion from an int to a string. It's in the conversion process that you can set the with from the displayed number. Use the streams manipulators setw and setfill for this purpose.
As a part of a larger program, I must convert a string of numbers to an integer(eventually a float). Unfortunately I am not allowed to use casting, or atoi.
I thought a simple operation along the lines of this:
void power10combiner(string deciValue){
int result;
int MaxIndex=strlen(deciValue);
for(int i=0; MaxIndex>i;i++)
{
result+=(deciValue[i] * 10**(MaxIndex-i));
}
}
would work. How do I convert a char to a int? I suppose I could use ASCII conversions, but I wouldn't be able to add chars to ints anyways(assuming that the conversion method is to have an enormous if statement that returns the different numerical value behind each ASCII number).
There are plenty of ways to do this, and there are some optimization and corrections that can be done to your function.
1) You are not returning any value from your function, so the return type is now int.
2) You can optimize this function by passing a const reference.
Now for the examples.
Using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result;
std::stringstream ss;
ss << deciValue.c_str();
ss >> result;
return result;
}
Without using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result = 0;
for (int pos = 0; deciValue[pos] != '\0'; pos++)
result = result*10 + (deciValue[pos] - '0');
return result;
}
EDITED by suggestion, and added a bit of explanation.
int base = 1;
int len = strlen(deciValue);
int result = 0;
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check.
result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int.
base *= 10; // This raises the base...it's exponential but simple and uses no outside means
}
This assumes the string is only numbers. Please comment if you need more clarification.
You can parse a string iteratively into an integer by simply implementing the place-value system, for any number base. Assuming your string is null-terminated and the number unsigned:
unsigned int parse(const char * s, unsigned int base)
{
unsigned int result = 0;
for ( ; *s; ++s)
{
result *= base;
result += *s - '0'; // see note
}
return result;
}
As written, this only works for number bases up to 10 using the numerals 0, ..., 9, which are guaranteed to be arranged in order in your execution character set. If you need larger number bases or more liberal sets of symbols, you need to replace *s - '0' in the indicated line by a suitable lookup mechanism that determines the digit value of your input character.
I would use std::stringstream, but nobody posted yet a solution using strtol, so here is one. Note, it doesn't perform handle out-of-range errors. On unix/linux you can use errno variable to detect such errors(by comparing it to ERANGE).
BTW, there are strtod/strtof/strtold functions for floating-point numbers.
#include <iostream>
#include <cstdlib>
#include <string>
int power10combiner(const std::string& deciValue){
const char* str = deciValue.c_str();
char* end; // the pointer to the first incorrect character if there is such
// strtol/strtoll accept the desired base as their third argument
long int res = strtol(str, &end, 10);
if (deciValue.empty() || *end != '\0') {
// handle error somehow, for example by throwing an exception
}
return res;
}
int main()
{
std::string s = "100";
std::cout << power10combiner(s) << std::endl;
}
I have an int that I want to store as a binary string representation. How can this be done?
Try this:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<32> x(23456);
std::cout << x << "\n";
// If you don't want a variable just create a temporary.
std::cout << std::bitset<32>(23456) << "\n";
}
I have an int that I want to first convert to a binary number.
What exactly does that mean? There is no type "binary number". Well, an int is already represented in binary form internally unless you're using a very strange computer, but that's an implementation detail -- conceptually, it is just an integral number.
Each time you print a number to the screen, it must be converted to a string of characters. It just so happens that most I/O systems chose a decimal representation for this process so that humans have an easier time. But there is nothing inherently decimal about int.
Anyway, to generate a base b representation of an integral number x, simply follow this algorithm:
initialize s with the empty string
m = x % b
x = x / b
Convert m into a digit, d.
Append d on s.
If x is not zero, goto step 2.
Reverse s
Step 4 is easy if b <= 10 and your computer uses a character encoding where the digits 0-9 are contiguous, because then it's simply d = '0' + m. Otherwise, you need a lookup table.
Steps 5 and 7 can be simplified to append d on the left of s if you know ahead of time how much space you will need and start from the right end in the string.
In the case of b == 2 (e.g. binary representation), step 2 can be simplified to m = x & 1, and step 3 can be simplified to x = x >> 1.
Solution with reverse:
#include <string>
#include <algorithm>
std::string binary(unsigned x)
{
std::string s;
do
{
s.push_back('0' + (x & 1));
} while (x >>= 1);
std::reverse(s.begin(), s.end());
return s;
}
Solution without reverse:
#include <string>
std::string binary(unsigned x)
{
// Warning: this breaks for numbers with more than 64 bits
char buffer[64];
char* p = buffer + 64;
do
{
*--p = '0' + (x & 1);
} while (x >>= 1);
return std::string(p, buffer + 64);
}
AND the number with 100000..., then 010000..., 0010000..., etc. Each time, if the result is 0, put a '0' in a char array, otherwise put a '1'.
int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;
for(int i = 0; i < numberOfBits; ++i) {
if ((decimal & (0x80000000 >> i)) == 0) {
binary[i] = '0';
} else {
binary[i] = '1';
}
}
binary[numberOfBits] = '\0';
string binaryString(binary);
http://www.phanderson.com/printer/bin_disp.html is a good example.
The basic principle of a simple approach:
Loop until the # is 0
& (bitwise and) the # with 1. Print the result (1 or 0) to the end of string buffer.
Shift the # by 1 bit using >>=.
Repeat loop
Print reversed string buffer
To avoid reversing the string or needing to limit yourself to #s fitting the buffer string length, you can:
Compute ceiling(log2(N)) - say L
Compute mask = 2^L
Loop until mask == 0:
& (bitwise and) the mask with the #. Print the result (1 or 0).
number &= (mask-1)
mask >>= 1 (divide by 2)
I assume this is related to your other question on extensible hashing.
First define some mnemonics for your bits:
const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;
Then you have your number you want to convert to a bit string:
int x = someValue;
You can check if a bit is set by using the logical & operator.
if(x & FIRST_BIT)
{
// The first bit is set.
}
And you can keep an std::string and you add 1 to that string if a bit is set, and you add 0 if the bit is not set. Depending on what order you want the string in you can start with the last bit and move to the first or just first to last.
You can refactor this into a loop and using it for arbitrarily sized numbers by calculating the mnemonic bits above using current_bit_value<<=1 after each iteration.
There isn't a direct function, you can just walk along the bits of the int (hint see >> ) and insert a '1' or '0' in the string.
Sounds like a standard interview / homework type question
Use sprintf function to store the formatted output in the string variable, instead of printf for directly printing. Note, however, that these functions only work with C strings, and not C++ strings.
There's a small header only library you can use for this here.
Example:
std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays "10101"
auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"
auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"
Solution without reverse, no additional copy, and with 0-padding:
#include <iostream>
#include <string>
template <short WIDTH>
std::string binary( unsigned x )
{
std::string buffer( WIDTH, '0' );
char *p = &buffer[ WIDTH ];
do {
--p;
if (x & 1) *p = '1';
}
while (x >>= 1);
return buffer;
}
int main()
{
std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
return 0;
}
This is my best implementation of converting integers(any type) to a std::string. You can remove the template if you are only going to use it for a single integer type. To the best of my knowledge , I think there is a good balance between safety of C++ and cryptic nature of C. Make sure to include the needed headers.
template<typename T>
std::string bstring(T n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}
Use it like so,
std::cout << bstring<size_t>(371) << '\n';
This is the output in my computer(it differs on every computer),
0000000000000000000000000000000000000000000000000000000101110011
Note that the entire binary string is copied and thus the padded zeros which helps to represent the bit size. So the length of the string is the size of size_t in bits.
Lets try a signed integer(negative number),
std::cout << bstring<signed int>(-1) << '\n';
This is the output in my computer(as stated , it differs on every computer),
11111111111111111111111111111111
Note that now the string is smaller , this proves that signed int consumes less space than size_t. As you can see my computer uses the 2's complement method to represent signed integers (negative numbers). You can now see why unsigned short(-1) > signed int(1)
Here is a version made just for signed integers to make this function without templates , i.e use this if you only intend to convert signed integers to string.
std::string bstring(int n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}