I am having some problems with writing a program for adding, subtracting, multiplying and dividing binary. the major problem i am having is being able to restricting the program to give output of 1s and 0s (the binary part) and also it needs to be able to manipulate the binary if it as decimals in them such as 101.1 or 1.0101. Below is a program i have found online during my research but i dont fully understand how it works as yet to implement my own nor does it capable of computing binary with decimals in them. I do not want to use arrays as it limits the maximum output depending on the bits you put aside to do these calculations.
Looking forward to some potential ideas.
#include<stdio.h>
int main(){
long int binary1,binary2;
int i=0,remainder = 0,sum[20];
printf("Enter any first binary number: ");
scanf("%ld",&binary1);
printf("Enter any second binary number: ");
scanf("%ld",&binary2);
while(binary1!=0||binary2!=0){
sum[i++] = (binary1 %10 + binary2 %10 + remainder ) % 2;
remainder = (binary1 %10 + binary2 %10 + remainder ) / 2;
binary1 = binary1/10;
binary2 = binary2/10;
}
if(remainder!=0)
sum[i++] = remainder;
--i;
printf("Sum of two binary numbers: ");
while(i>=0)
printf("%d",sum[i--]);
return 0;
}
That code may work if you have fixed-point decimal numbers.
I'd suggest to parse the string to a double number and then use the standard arithmetic.
To parse the number you split the string on the "." decimal separator.
You parse the integer part from right to left multiplying the ones and the zeroes by growing powers of two, starting from 0. Then you parse the other string (decimal part) multiplying by the inverse of growing powers of two, starting from one.
For example:
110.11001
110 + 11001
Integer, reversed = 0*2^0 + 1*2^1 + 1*2^2
Decimal = 1*2^-1 + 1*2^-2 + 0*2^-3 + 0*2^-4 + 1*2^-5
Related
I am trying to reverse a two digit number, and I understand there may be better ways of doing this, but I am curious now why the way I chose does not work.
If I input 48, it produces 84 (a successful reversal).
If I input 84, it produces 38. If I input 47, it produces 64. These are just some examples of unsuccessful reversals.
int digit_one, digit_two, input;
float a, b;
printf("Enter a two-digit number: ");
scanf("%d", &input);
a = input * 0.1; // turns the two digit input figure into a float with a digit after the decimal point
digit_one = a; // turns the float into an integer, eliminating the digit after the decimal point
b = a - digit_one; // produces a float that has a 0 before the decimal point, and a digit after the decimal point
digit_two = b * 10; // moves the digit that was after the decimal point, to before the decimal point
printf("The reversal is: %d%d\n", digit_two, digit_one);
Thank you!
a - digit_one is a fractional number. If it's slightly less than the exact result (because for example 0.7 cannot be represented exactly as a float), then (a - digit_one) * 10 will be slightly less than the desired integer, and so digit_two will be one less than you expect.
You can avoid floating point, and write int digit_one, digit_two = input / 10, input % 10;
Working with floats is not the best approach here. With the input "84", b * 10 = 3.999996 which is 3 when you convert it to an integer.
This is a classic computer science problem with floats. Here are some links where this has been explained very well:
Is floating point math broken?
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Your problem can be solved differently:
int digit_one, digit_two, input, a, b;
printf("Enter a two-digit number: ");
scanf("%d", &input);
digit_one = input % 10;
digit_two = (input / 10) % 10;
printf("The reversal is: %d%d\n", digit_one, digit_two);
int result =0;
do{
result = (result * 10) + (input % 10);
input /= 10;
} while(input)
printf("The reversal is: %d\n", result);
You can print the 'result' variable to get any integer value irrespective of 2 digit or 3 digit
I was trying to satisfy this question: Write a function print_dig_float(float f) which prints the value of each digit of a floating point number f. For example, if f is 2345.1234 the print_dig_float(f) will print integer values of digits 2, 3, 4, 5, 1, 2, 3, and 4 in succession.
What I did is: given a number with some decimals, I try to move the digits to the left (Ex: 3.45 -> 345) by multiplying it with 10. After that, I store each digit in an array by taking the remainder and put it in an element. Then, I print them out.
So my program looks like this:
#include <stdio.h>
void print_dig_float(float f);
int main(int argc, char const *argv[]) {
print_dig_float(23432.214122);
return 0;
}
void print_dig_float(float f) {
printf("%f\n", f);
int i = 0, arr[50], conv;
//move digits to the left
do {
f = f * 10;
conv = f;
printf("%i\n", conv);
} while (conv % 10 != 0);
conv = f / 10;
//store digits in an array
while (conv > 1) {
arr[i] = conv % 10;
conv = conv / 10;
i++;
}
for (int j = i - 1; j >= 0; j--) {
printf("%i ", arr[j]);
}
printf("\n");
}
When I tested it with the number: 23432.214122, this is what I get (according to Linux terminal):
23432.214844
234322
2343221
23432216
234322160
2 3 4 3 2 2 1 6
The problem is that, as you can see above, the computer arbitrarily changes the decimal digits at the end of the number even before I do anything with it. I don't know if this is my fault or the computer's fault for this problem.
Per C 2018 5.2.4.2.2, a floating-point number is represented with a sign, a fixed base to some exponent, and a numeral formed of digits in that base. Most commonly, two is used as the base.
When the base is two, 23432.214122 cannot be represented in floating-point, because every representable number is necessarily some integer multiple of a power of the base (possible a negative power). 23432.214122 is not a multiple of ½, ¼, ⅛, 1/24, 1/25, or any other power of two.
When 23432.214122 is used in source code, it is converted to a value that is representable. In good C implementations, the nearest representable value is used, but the C standard permits either the representable value that is the nearest larger or nearest smaller value to be used. Other than this, the digits that appear are not arbitrary; they are a consequence of the mathematics.
When IEEE-754 binary32 is used for float, the representable value nearest to 23432.214122 is exactly 23432.21484375.
Because, when a C implementation uses base two for floating-point numbers, floating-point numbers have binary digits and do not have decimal digits. It is generally not meaningful to attempt to extract decimal digits from a thing that does not have decimal digits. It is possible to determine the decimal digits that were in an original numeral up to some limit affected by the floating-point format. However, “23432.214122” has too many digits to do this with a 32-bit floating-point type. With a 64-bit type, as is commonly used for double, you could recover the original digits providing you knew how many decimal digits there were to start with. It is not generally possible to recover the original numeral without that information—as you have seen the trailing digits will be different, and there is no indication in the floating-point number itself of where the differences start.
I came from python and it was easy to get the middle digit of an integer, for example, from 897 I want the 9:
>>> num = 897
>>> num2 = int(str(num)[1])
>>> num2
9
But how i can do this on C? It's so difficult to convert into string...
Getting a single digit as an int can be done mathematically:
int num = 897;
int dig1 = (num / 1 ) % 10;
int dig2 = (num / 10 ) % 10;
int dig3 = (num / 100 ) % 10;
Division by one on the first line is only for illustration of the concept: you divide by n-th power of ten, starting with 100 = 1.
You can try the modulus operator (%).
In your case
num = 897
lastDigit = num%10; // Which returns 7
lastDigit/= 10;
secondLastDigit = lastDigit%10; //Which returns 9
Do this using a while loop for as long as you want. EG.
while(num>0)
{
digit = num%10;
num/=10;
}
The closest approximation in C to the given Python fragment, and its str operator, is sprintf/snprintf:
int num = 897;
char numstr[30];
sprintf(numstr, "%d", num);
char num2 = numstr[1];
int num2n = num2 - '0';
printf("%d\n", num2n);
To guard against buffer overflow, it's safer to get in the habit of using snprintf rather than sprintf:
snprintf(numstr, sizeof(numstr), "%d", num);
Instead of sprintf and %d, some systems provide an itoa() function (the opposite of atoi) for converting integers to strings, but it's not standard. For more information about converting numbers to strings, see Converting int to string in C.
This is "harder" in C than it is in Python for a couple of reasons. Constructing strings from numbers typically involves calls to snprintf, which is both more flexible and more of a nuisance than just calling str(). You typically have to worry about how big the destination array (here numstr) needs to be; this difficulty stems from C's lack of a first-class string type. And C has no convenience method for converting back and forth between digit characters and their values, so C programmers get used to adding and subtracting the constant '0' (or, if they like to make more work for themselves, 48).
(And the other part of the difficulty stems, I guess, from practicality. C was originally designed for writing operating systems and text editors and system utilities and things. How often do you need the middle digit of a number, anyway?)
The problem: user inputs two numbers: a big one, and a small one.
The small number is the number of digits from the last digit that will transfer into the front, and the remaining numbers will follow.
For example: if the big number is 456789 and the small one is 3, the result will be: 789456.
my idea was as follows:
if(...) {
newNum = BigNumber%(10*SmallNumber);
printf("%d", remainder");
SmallNumber--;
}
but it doesn't print in the order I was hoping for, digit by digit, and I can't understand why.
If using arrays would be allowed, it was no problem. Also I'm not allowed to use string.length, which also make it lots easier.
Rotating a number can be performed as a combination of cuts, shifts, and additions. For example, if you have a number 123456789 and you need to rotate it by 3, you can do it as follows:
Cut off the last three digits 123456789
Shift the remaining number by three digits to make 123456789
Shift the last three digits by six to make 789000000
Add the two numbers together 789000000 + 123456 to get the result 789123456.
Here is how you do these operations on decimal numbers:
Cutting off the last k digits is done with modulo % 10k
Shifting right by k digits is equivalent to integer division by 10k
Shifting left by k digits is equivalent to multiplication by 10k
Figuring out the number of significant digits in a number can be done by repeated integer division by ten.
Addition is done the usual way.
I think below code would help you -
//Here size = number of digits in bignumber-1
while(smallnumber--) {
temp = (bignumber - bignumber%pow(10,size))/(pow(10,size);
bignumber = bignumber%pow(10,size);
bignumber = bignumber*10 + temp;
}
Try this version:
#include <stdio.h>
#include <math.h>
int main(void)
{
long int num = 34234239;
int swap = 5, other;
long int rem = num % (int)(pow(10,swap)); /*The part that is shifted*/
other = log10(num-rem)+1-swap; /*Length of the other part*/
/* Result = (part to shift)*(Other part's length) + (Other part)*(Shifts) */
num = rem*(int)pow(10,other) + (num-rem)/(int)pow(10,swap);
printf("%ld\n",num);
return 0;
}
I am trying to truncate everything past the hundredths decimal. (13.4396 would be 13.43) Sholdn't it always or never work?
I have this formula that works 99%:
input = (( (double) ((int)(orgInput * 100)) ) / 100) ;
Then I have this formula sequence that is arithmetically equivalent:
input = (orgInput * 100);
input = (int) input;
input = (double) (input);
input = input / 100;
These inputs do not give the desired result (Formula truncates and round down, while the broken down steps output the desired result):
12.33
99.99
22.22
44.32
56.78
11.11
And then an even bigger mystery to me is why 33.30 does not work on either of them. Below is my program that runs continuously to demonstrate my problem.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
double orgInput, input;
while (4!=3)
{
printf("Please enter the dollar amount (up to $100) => ");
scanf("%lf", &orgInput);
/* Truncates anything past hundredths place */
input = (orgInput * 100) ;
printf("\n1. input is %g \n ", input);
input = (int) input ;
printf("\n2. input is %g \n ", input);
input = (double) (input) ;
printf("\n3. input is %g \n", input);
input = input / 100 ;
printf("\n4. input is %.2lf \n", input);
input = (( (double) ((int)(orgInput * 100)) ) / 100) ;
printf("\nUsing the formula the input is %.2lf \n \n\n", input);
}
system("PAUSE");
return 0;
}
Thank you in advance!!!! P.S. Sorry for the formatting I am still getting used to stackoverflow
Key phrases:
Double to int conversion
Precision error
I think you are suffering from floating-point precision errors.
You should be able to fix this by doing:
const double epsilon = 1e-10; // Or some suitable small number
input = floor(orgInput * 100 + epsilon) / 100;
An alternative is to stop this from happening on input. Instead of reading in a double, you read a string and then parse that to get out the dollar and cents amount (cents being exactly 2 digits following the decimal point, if any). You can then ignore everything else.
In general, if you are working with money truncated to cents, you might be best to keep it in cents and use integers. Either that or round instead of truncate (for my above example, that would mean an epsilon of 0.5).
You need to understand that floats are represented in binary as:
2^(exponent) * mantissa
Exponent is a standard integer, but mantissa (a value between 1 and 2) is a number of bits where each bit represents a fraction: 1, 1/2, 1/4, 1/8, 1/16 and so on... Therefore it is not possible for the mantissa to represent certain values exactly, it will have an accuracy of +/- some fraction.
For example you mentioned 33.30. As a float 33.30 can only be: 2^5 * mantissa.
In this case the mantissa has to be 33.30/32 = 1.40625 exactly. But by making it out of the fractions the closest it can be is be is: 1.0406249999999999111821580299874767661094. So the actual value of the double is not 33.30, its 33.2999999999999971578290569595992565155029296875, which of course rounds DOWN to 33.29 when you do the type cast to integer.
The correct way to fix your program is not to scan in a float in the first place. You should be scanning in two integers seperated by decimal, and if scanf returns a value that indicates it did not scan two integers, then scan it as one integer for the case of a dollar only value.
Sadly, printf works by conversions to ints inside it and will not properly print any double precision floats that have more than 6 decimal places, which is why you see it as 33.30 even through you are asking printf to print the value of a double.
Most machines use binary, not decimal floating point. While binary-to-decimal conversion always gives exact values (in theory), it's impossible to convert from decimal to binary without rounding (I'm not considering the impractical case when numbers can have infinite number of digits).
As such, all your binary floating-point numbers are going to be slightly off of what they would've been in decimal.
The only 1-digit decimal fractions that can be represented in binary are: .0, .5.
Likewise, 2-digit decimal fractions exactly representable in binary are: .00, .25, .50, .75 (see here).
If you want, which I doubt, you can round to the nearest fraction of the four.