I'm currently working on a program that is meant to take an octal fraction as an input and convert it to a decimal fraction. So far, I have the part of code that will convert the portion before the decimal point to decimal, just not the floating points after the decimal point. I was trying to use modulus, but was unsuccessful because of my variable being a float.
Is there a way to convert the remaining numbers after the decimal point to decimal from octal? I have posted my code below. Any help is appreciated. Thanks!
int main()
{
float num;
int rem = 0;;
int dec = 0;
int i = 0;
cout << "Please enter a number with a decimal point: ";
cin >> num;
double ohalf = num - (int)num;
int half = num;
while (half != 0)
{
rem = half % 10;
half /= 10; //Converts first have to decimal
dec += rem *= pow(8, i);
i++;
}
cout << dec;
i = -1;
while (ohalf != 0)
{
rem = ohalf *pow(8, i); //Converts second half to decimal. *This is where I am stuck*
i--;
}
cout << rem;
_getch();
return 0;
}
Going with the idea that one can remove the decimal point just by multiplying with the base often enough:
"123.456" in base 16
=> BASE16("1234.56")/16
=> BASE16("12345.6")/(16*16)
=> BASE16("123456")/(16*16*16)
or
"123.456" in base 8
=> BASE8("1234.56")/8
=> BASE8("12345.6")/(8*8)
=> BASE8("123456")/(8*8*8)
So all we need to know is the number of places behind the decimal point.
Then we can remove it and use std::stoi to convert the remaining string in the wanted base.
As a last step we need divide again through base^number_of_places_after_decimal.
Putting everything together you get something like this:
#include <iostream>
#include <string>
#include <cmath>
using std::cout;
using std::cin;
using std::string;
int main()
{
int base = 8;
string value;
cout << "Please enter a number with a decimal point: ";
cin >> value;
size_t ppos = value.find('.');
if (ppos != string::npos) {
value.replace(ppos,1,"");
} else {
ppos = value.size();
}
size_t mpos = 0;
double dValue = (double)std::stoi(value, &mpos, base);
if (mpos >= ppos)
{
dValue /= std::pow(base, (mpos - ppos));
}
std::cout << dValue << '\n';
return 0;
}
If you're confident that both the integer and fractional parts of your floating-point value won't overflow the range of long long int, you could parse both parts separately with std::stoll(), then divide the fractional part by the appropriate power of 8:
#include <cmath>
#include <stdexcept>
#include <string>
double parse_octal_fraction(const std::string s)
{
std::size_t dotpos;
auto whole = std::stoll(s, &dotpos, 8);
if (dotpos+1 >= s.length())
// no fractional part
return whole;
std::size_t fract_digits;
auto frac = std::stoll(s.substr(dotpos+1), &fract_digits, 8);
if (s.find_first_not_of("01234567", dotpos+1) != std::string::npos)
throw std::invalid_argument("parse_octal_fraction");
return whole + frac / std::pow(8, fract_digits);
}
#include <iostream>
int main()
{
for (auto input: { "10", "0", "1.", "0.4", "0.04", "1.04", "1.04 ", "1. 04"})
try {
std::cout << input << " (octal) == " << parse_octal_fraction(input) << " (decimal)" << std::endl;
} catch (const std::invalid_argument e) {
std::cerr << "invalid input: " << e.what() << " " << input << std::endl;
}
}
The test inputs shown give this output:
10 (octal) == 8 (decimal)
0 (octal) == 0 (decimal)
1. (octal) == 1 (decimal)
0.4 (octal) == 0.5 (decimal)
0.04 (octal) == 0.0625 (decimal)
1.04 (octal) == 1.0625 (decimal)
invalid input: parse_octal_fraction 1.04
invalid input: parse_octal_fraction 1. 04
in your code
while (ohalf != 0)
{
rem = ohalf *pow(8, i); //Converts second half to decimal. *This is where I am stuck*
i--;
}
ohalf will never be equal to zero so It may have lead to infinite loop
Related
This is my code that I have currently but it always outputs 0 I'm trying to get it to output the reverse of the input including the negative for example -123425 will be 524321-:
#include<iostream>
using namespace std;
int main() {
int number;
bool negative;
cout << "Enter an integer: ";
cin >> number;
while (number != 0) {
number % 10;
number /= 10;
}
if (number < 0) {
negative = true;
number = -number;
cout << number << "-";
}
else {
negative = false;
}
cout << number << endl;
return EXIT_SUCCESS;
}
You could convert the input to a std::string, then reverse its content with std::reverse.
#include <algorithm> // reverse
#include <cstdlib> // EXIT_SUCCESS
#include <iostream> // cin, cout, endl
#include <string> // string, to_string
using namespace std;
int main()
{
cout << "Enter an integer: ";
int number;
cin >> number;
auto str = to_string(number);
reverse(str.begin(), str.end());
cout << str << endl;
return EXIT_SUCCESS;
}
Reading to an int first - and not to a std::string - makes sure that we parse a valid integer from the input. Converting it to a std::string allow us to reverse it. This let us feed inputs like -042 and -0 to the program, and get 24- and 0 as a result, not 240- and 0-.
After the first loop
while (number != 0) {
number % 10;
number /= 10;
}
the variable number is equal to 0.
So the following if statement
if (number < 0) {
negative = true;
number = -number;
cout << number << "-";
}
else {
negative = false;
}
does not make sense.
Pay attention to that it can happen such a way that a reversed number can not fit in an object of the type int. So for the result number you should select a larger integer type.
Here is a demonstrative program that shows how the assignment can be done.
#include <iostream>
int main()
{
std::cout << "Enter an integer: ";
int n = 0;
std::cin >> n;
bool negative = n < 0;
const int Base = 10;
long long int result = 0;
do
{
int digit = n % Base;
if ( digit < 0 ) digit = -digit;
result = Base * result + digit;
} while ( n /= Base );
std::cout << result;
if ( negative ) std::cout << '-';
std::cout << '\n';
return 0;
}
Its output might look like
Enter an integer: 123456789
987654321-
I think trying to visualize the process of your program is a great way to see if your solution is doing what you expect it to. To this end, let's assume that our number is going to be 12345. The code says that while this is not equal to 0, we will do number % 10 and then number /= 10. So if we have 12345, then:
number % 10 --> 12345 % 10 --> 5 is not assigned to any value, so no change is made. This will be true during each iteration of the while loop, except for different values of number along the way.
number /= 10 --> 12345 /= 10 --> 1234
number /= 10 --> 1234 /= 10 --> 123
number /= 10 --> 123 /= 10 --> 12
number /= 10 --> 12 /= 10 --> 1
number /= 10 --> 1 /= 10 --> 0 (because of integer division)
Now that number == 0 is true, we proceed to the if/else block, and since number < 0 is false we will always proceed to the else block and then finish with the cout statement. Note that the while loop will require number == 0 be true to exit, so this program will always output 0.
To work around this, you will likely either need to create a separate number where you can store the final digits as you loop through, giving them the correct weight by multiplying them by powers of 10 (similar to what you are hoping to do), or cast your number to a string and print each index of the string in reverse using a loop.
Quite simple:
int reverse(int n){
int k = abs(n); //removes the negative signal
while(k > 0){
cout<<k % 10; //prints the last character of the number
k /= 10; //cuts off the last character of the number
}
if(n < 0) cout<<"-"; //prints the - in the end if the number is initially negative
cout<<endl;
}
int main(){
int n = -1030; //number you want to reverse
reverse(n);
}
If you don't want to use String or have to use int, here is the solution.
You want to check the negativity before you make changes to the number, otherwise the number would be 0 when it exit the while loop. Also, the modulus would be negative if your number is negative.
number % 10 only takes the modulus of the number, so you want to cout this instead of just leaving it there.
The last line you have cout << number << endl; will cout 0 since number has to be 0 to exit the while loop.
if(number < 0) {
number = -number;
negative = true;
}
while (number != 0) {
cout << number % 10;
number /= 10;
}
if (negative) {
cout << "-"<< endl;
}
EDIT: With a broader assumption of the input taking all int type values instead of the reversed integer being a valid int type. Here is a modified solution.
if(number < 0) {
negative = true;
}
while (number != 0) {
cout << abs(number % 10);
number /= 10;
}
if (negative) {
cout << "-"<< endl;
}
using namespace std;
int main()
{
int number,flag=1;
long long int revnum=0;
bool negative;
cout << "Enter an integer: ";
cin >> number;
if(number<0)
{ negative=true;
}
while (number > 0) {
revnum=revnum*10+number %10;
number /= 10;
}
if (negative)
{ revnum=(-revnum);
cout << revnum << '-'<<endl;
}
else
{ cout<<revnum<<endl;
}
return 0;
}
A few changes I did -
checking the number whether it's negative or positive
if negative converting it to positive
3.reversing the number with the help of a new variable revnum
4.and the printing it according to the requirement
To reverse the num-
revnum=revnum*10 + number%10
then num=num/10
like let's try to visualize
1.take a number for example like 342
2.for 1st step revnum=0 so revnum*10=0 and num%10=2 , so revnum will be 2
and the number now is num/10 so 34
4.next now rev = 2 the rev*10=20 and num%10=4 then rev*10 + num/10 =24
5.finally we get 243
Hope it helps :)
edit:-
just a small edit to solve the problem of the overflow of int , made revnum as long long int.
I wrote code to convert decimal fraction number to its binary equivalent. It compiles fine but when executed hangs. The code here prints only first four digits of the binary conversion and if the number if with more than 4 digits, it shows '...' after it. On execution it hangs. Help!
#include <iostream>
using namespace std;
int main()
{
int i, x[10];
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num>=0 && num<=1)
{
i=1;
while (num!=1.000)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
if (i>4)
{
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
cout << "...";
}
else
{
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
}
}
else
{
cout << "The number entered is out of range.";
}
return 0;
}
The first obstacle is the infinite while loop:
Assuming input num=0.5
after first iteration, i=1, x[0]=1, num=0.0
after second iteration, i=2, x[1]=0, num=0.0
Continue forever, i=..., x[i-]1=0, num=0.0
With nothing to break the loop.
while (num!=1.000)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
To fix, consider few changes. There might be other issues.
put a limit on the while loop (i<10 should be a good condition, as this is the size of the x array), or i=4, as this is the maximum output.
The break condition for the while loop should probably be 'num != 0', or even better (num > 1e-7, or other small value).
float has 23 bit in mantissa, maybe it is because you are assign x[i] with i greater than 9.
try this:
//stop when you get four bits
while (i< 5)
Original code has several issues:
1 For input num=.5 and similar (really for all values) cycle never ends (dash-o suggested fix ideas)
2 array x[10] is overflowed with undefined behavior (Edney)
3 nitpicking: 1 is not a “fraction” and better check for a range 0 <= num < 1 instead of 0 <= num <= 1(see also OP printing code; 1 could be added); we could use x[4] with 0<=i <=3
4 string could also be used (PaulMcKenzie). Really “>>” uses string processing for parsing and calculating binary equivalent from which by multiplying by 2 (left shit) and truncation fractional part the code calculates target bits. Both approaches give correct identical results; implementing by string we need to add internal to operator “>>” implementation code to parsing valid formats for floats (decimals) such as 3.14e-1, .2718, 1e-1, etc.
This fix follows OP:
#include <iostream>
using namespace std;
int main()
{
int i, x[5];
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num>=0 && num<1)
{
i=1;
while (i<=4)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
if (num>0)
cout << "...";
}
else
{
cout << "The number entered is out of range.";
}
return 0;
}
This code is without cycles (they are in code implementing “>>”, bitset):
#include <iostream>
#include <bitset>
using namespace std;
int main () {
const int digits = 4;
int fraction;
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num >= 0 && num < 1) {
fraction = num = num * pow (2, digits);
cout << "The binary equivalent is 0.";
cout << bitset<digits> (fraction);
if (num - fraction > 0) cout << "...";
}
else cout << "The number entered is out of range.";
}
So, what needs to be done is: enter a real number and print the sum of its first 4 digits after the decimal point. E.g.: I enter 5.1010. I get to the point where I need to multiply 0.1010 by 10000 so it can become an integer, but the result I'm getting is 1009 instead of 1010 and everything falls apart after that.
I'd be forever thankful if someone can explain to me why does that happen.
#include<iostream>
using namespace std;
int main()
{
double n;
cout<<"Enter a positive real number: ";
do
{
cin>>n;
if(n<=0) cout<<"The number must be positive, enter again: ";
}while(n<=0);
//storing the fractional part in a var
int y=n;
double fr=n-y;
//turning the fractional part into an integer
int fr_int=fr*10000;
cout<<fr_int<<endl;
//storing each of the digits in a var
int a=fr_int/1000;
int b=fr_int/100%10;
int c=fr_int/10%10;
int d=fr_int%10;
cout<<"The sum of the first 4 digits is: " << a+b+c+d;
return 0;
}
You could simply change the code as follows, then it should be working.
n *= 10000;
int Integer = n;
int i = 4;
int sum = 0;
while(i--)
{
sum += (Integer%10);
Integer /= 10;
}
std::cout << "The sum of the first 4 digits is: " << sum;
Here is the output: https://www.ideone.com/PevZgn
Update:A generalized soln would be using std::string. However, would be great if the code is capable of handling exceptions in the case of non-numeric has been submitted by the user.
#include <iostream>
#include <string>
int main()
{
std::string Number;
double tempNum = 0.0;
std::cout << "Enter a positive real number: ";
do
{
std::cin >> Number;
tempNum = std::stof(Number);
if(tempNum <= 0)
std::cout << "The number must be positive, enter again: ";
}while(tempNum <= 0);
bool Okay = false;
int sum = 0;
int i = 4;
for(const auto& it: Number)
{
if(Okay && i > 0)
{
sum += static_cast<int>(it - '0');
--i;
}
if(it == '.') Okay = true;
}
std::cout << "The sum of the first 4 digits is: " << sum;
return 0;
}
I think you should add 0.5 before casting because the compile will always truncate the number.
In C++11 you can use std::round.
Floating points and doubles in C++ aren't able to represent all decimal numbers accurately. In particular, 0.1, it cannot represent faithfully.
If you must be guaranteed that you get accurate results, you should either use fixed point math or a bignumber library.
Please i need help debugging the code below.
I am suppose to produce a code using functions that converts binary numbers to decimal or octal.
I keep getting error at the switch statement "error too few argument in function call".
#include <iostream.>
long int menu();
long int toDeci(long int);
long int toOct(long int);
using namespace std;
int main ()
{
int convert=menu();
switch (convert)
{
case(0):
toDeci();
break;
case(1):
toOct();
break;
}
return 0;
}
long int menu()
{
int convert;
cout<<"Enter your choice of conversion: "<<endl;
cout<<"0-Binary to Decimal"<<endl;
cout<<"1-Binary to Octal"<<endl;
cin>>convert;
return convert;
}
long int toDeci(long int)
{
long bin, dec=0, rem, num, base =1;
cout<<"Enter the binary number (0s and 1s): ";
cin>> num;
bin = num;
while (num > 0)
{
rem = num % 10;
dec = dec + rem * base;
base = base * 2;
num = num / 10;
}
cout<<"The decimal equivalent of "<< bin<<" = "<<dec<<endl;
return dec;
}
long int toOct(long int)
{
long int binnum, rem, quot;
int octnum[100], i=1, j;
cout<<"Enter the binary number: ";
cin>>binnum;
while(quot!=0)
{
octnum[i++]=quot%8;
quot=quot/8;
}
cout<<"Equivalent octal value of "<<binnum<<" :"<<endl;
for(j=i-1; j>0; j--)
{
cout<<octnum[j];
}
}
I am suppose to produce a code using functions that converts binary numbers to decimal or octal.
There's no such thing like converting binary numbers to decimal or octal based on numerical representations as
long int toDeci(long int);
long int toOct(long int);
Such functions are completely nonsensical for any semantical interpretation.
Numbers are numbers, and their textual representation can be in decimal, hex, octal or binary format:
dec 42
hex 0x2A
oct 052
bin 101010
are all still the same number in a long int data type.
Using the c++ standard I/O manipulators enable you to make conversions of these formats from their textual representations.
I'm not sure that I understand what you're trying to do. Here's an example that might help you (demo):
#include <iostream>
int main()
{
using namespace std;
// 64 bits, at most, plus null terminator
const int max_size = 64 + 1;
char b[max_size];
//
cin.getline( b, max_size );
// radix 2 string to int64_t
uint64_t i = 0;
for ( const char* p = b; *p && *p == '0' || *p == '1'; ++p )
{
i <<= 1;
i += *p - '0';
}
// display
cout << "decimal: " << i << endl;
cout << hex << "hexa: " << i << endl;
cout << oct << "octa: " << i << endl;
return 0;
}
I am making a console based calculator application. The application processes user keypresses to perform its operations. Integral inputs work fine; however, I am facing problems writing the code for the case where the user presses a backspace to erase a decimal number.
The code that I wrote to erase decimal spaces is as follows:
decimalcount--; // number of decimal places is subtracted by 1
lnum -= fmod (lnum, pow (10, -decimalcount + 1)); // subtraction
cout << setprecision (decimalcount) << lnum << endl; // display the code
However, for certain numbers like 12.00400679, the values are being improperly subtracted:
12.00400679
12.00400670
12.0040060
12.004000
12.00400
12.0040
12.000
11.90
11.0
10
The full source of the program is as below:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <conio.h>
using namespace std;
int sgn (double x)
{
if (x < 0)
{
return -1;
}
return 1;
}
int main ()
{
cout.setf (ios::fixed);
double lnum = 0, expr = 0;
int decimalcount = 0;
char ch, op;
while (true)
{
ch = _getch ();
if (isdigit (ch))
{
if (! decimalcount)
{
if (sgn (lnum) == sgn (lnum * 10 + sgn (lnum) * (ch - 48)))
{
lnum = lnum * 10 + sgn(lnum) * (ch - 48);
cout << setprecision (0) << lnum << endl;
}
}
else
{
if (decimalcount < 9)
{
lnum += sgn (lnum) * (ch - 48) * pow (10, -decimalcount);
cout << setprecision (decimalcount) << lnum << endl;
decimalcount++;
}
}
}
else if (ch == '\b')
{
if (! decimalcount)
{
lnum -= fmod (lnum, 10);
lnum /= 10;
cout << setprecision (0) << lnum << endl;
}
// This is where I am having problems
else
{
decimalcount--;
lnum -= fmod (lnum, pow (10, -decimalcount + 1));
cout << setprecision (decimalcount) << lnum << endl;
}
}
else if (ch == '.')
{
if (! decimalcount)
{
decimalcount = 1;
cout << setprecision (decimalcount) << lnum << endl;
}
}
else if (ch == 'x')
{
return 0;
}
}
}
Can anyone show me where I am doing it wrong?
Thanks in advance,
You're converting too early. During input, you should keep the
input as a string, and only convert to your internal format when
the input is finished, and you're ready to do the calculations.
But you seem to be doing things the hard way. Why not just use
std::getline on std::cin, and parse the text you receive?
That way, the system handles things like back space, and you
don't have to. If for some reason this isn't acceptable, you
should still factor the input out into a separate function,
which does more or less the same thing.
It is because those values cannot be exactly represented by a floating point number. Its worth reading up on how floating point is represented in memory.
If you require exact decimal places, you may be better off using fixed-point arithmetic. However, implementing trig functions etc may be annoying unless you convert to floating point for such operations.
You should avoid performing arithmetic operations on the number, as that may alter the significant digits you want to keep. Instead, you can convert it to a string and truncate it and then convert back when you need the actual arithmetic value. Examples:
double d;
// ...
std::ostringstream sstream;
sstream << d;
std::string str = sstream.str();
Or:
char str[10];
snprintf(str, 10, "%g", d);
But in general, I'd go with James Kanze's answer and store all input as strings and only convert to numeric values at the end.