Divide by 2 and round up in C without libraries [duplicate] - c

This question already has answers here:
Rounding integer division (instead of truncating)
(26 answers)
Closed 1 year ago.
I need to know the price of all the offices that a company hires, knowing that you pay per office and there can be room for two workers per room, the problem is that I cannot use libraries or if...
monthlyPrice = oficePrice * (workers/2);
monthlyPrice = 100 * (7 / 2) = 350$
I need to either round up or find me another mathematical formula.
it could be done with a realtointegrer, i don´t now... :(
Thanks. Pablo.

The simpliest way to round a floating point number x is as follows:
return (int)(x + 0.5);

I would suggest that you use the / and % operators.
/ will give you the integer section (left side of decimal point) for a division operation.
% will give you the remainder section (right side of the decimal point) of a division operation.
e.g.
7/2 gives 3
7%2 gives 1
You can then decide whether you wish to round up the result depending on the value returned by using %.
Ah I see that you're not allowed to use the if ... else ... construct. What about ... ? ... : ...?

For money I would use fixed point.
//one cent is minimum we care
#define MULT (100)
#define MAKE_FIXED(d) ((int32_t)(d * MULT))
#define MAKE_REAL(f) (((double)(f)) / MULT)
int32_t mulf(int32_t a, int32_t b)
{
int64_t part = (int64_t)a * b;
return part/MULT;
}
int32_t divf(int32_t a, int32_t b)
{
int64_t part = ((int64_t)a * MULT) / b;
return part;
}
int main(void)
{
int32_t officeprice = MAKE_FIXED(100);
int32_t workers = MAKE_FIXED(7);
printf("%f\n", MAKE_REAL(mulf(officeprice, divf(workers,MAKE_FIXED(2)))));
}

Related

Noob Question! Why does this always return 0? [duplicate]

This question already has answers here:
Integer division returns 0 in C
(2 answers)
Closed last year.
I wanted to get the convert from Fahrenheit to Celsius with this program, but it always returns 0. Why?
#include <stdio.h>
int main() {
int fahr = 15, celsius;
celsius = (5 / 9) * (fahr - 32);
printf("%d\n", celsius);
return 0;
}
It seems that the problem is in celsius = (5 / 9) * (fahr - 32);. I already know that celsius = 5 * (fahr - 32) / 9; fixes the problem. But why did the first one return zero?
In short, when performing arithmetic operations, C compiler has to choose which number format to use. To do this, it won't pick the one of the first operand, nor try to guess what the result would be, but will opt for the most precise type of both operand.
In your particular example, (5 / 9) use two integers, so the result will remain an integer too, thus zero.
A quick way to fix this is to directly specify a decimal in your constant :
(5 / 9.0)
The other answers and comments are steering you in the correct direction with regards to integer division vs floating point. But if you want to avoid floating point altogether and still produce a correct answer (as an integer), then structure your equation such that division comes last.
Since (x/y) * z is the same as (x * z)/y, then this holds:
celsius = (5 * (fahr - 32)) / 9;
In C, if you do a division between two integer type variables, you get an integer back.
So this:
(5 / 9)
gets a result of 0.555, which is then rounded down. (In C, integer division rounds towards zero.)
If you changed it like this, it would be floating point division instead:
celsius = (5.0 / 9) * (fahr - 32);

C: is there anyway i can get the modulo operator to work on non integer values? [duplicate]

This question already has answers here:
How to use % operator for float values in c
(6 answers)
Floating Point Modulo Operation
(4 answers)
Closed 2 years ago.
I need to reset the value of a variable called theta back to 0 everytime its value reaches or exceeds 2 PI. I was thinking something along the lines of:
int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++)
theta = (theta + inc) % 2*PI;
Of course it wont work because % doesn't work on floating points in C. Is there another equivalent or better way to achieve what I'm trying to do here? All replies are welcome. Thanks
Use the standard fmod function. See https://en.cppreference.com/w/c/numeric/math/fmod or 7.2.10 in the C17 standard.
The fmod functions return the value x − n y , for some integer n such that, if y is nonzero, the result
has the same sign as x and magnitude less than the magnitude of y.
So theta = fmod(theta, 2*PI) should be what you want, if I understand your question correctly.
If it really must be done on float instead of double, you can use fmodf instead.
Since division is really just repeated subtraction, you can get the remainder by checking if the value is at least 2*PI, and if so subtract that value.
int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++) {
theta += inc;
if (theta >= 2*PI) theta -= 2*PI;
}
Note that because the amount of the increment is less than the 2*PI limit we can do the "over" check just once. This is likely cheaper than the operations that would be involved if fmod was called. If it was more you would at least need while instead, or just use fmod.

Does pow() work for int data type in C? [duplicate]

This question already has answers here:
Strange behaviour of the pow function
(5 answers)
Closed 7 years ago.
I was simply writing a program to calculate the power of an integer. But the output was not as expected. It worked for all the integer numbers except for the power of 5.
My code is:
#include <stdio.h>
#include <math.h>
int main(void)
{
int a,b;
printf("Enter the number.");
scanf("\n%d",&a);
b=pow(a,2);
printf("\n%d",b);
}
The output is something like this:
"Enter the number. 2
4
"Enter the number. 5
24
"Enter the number. 4
16
"Enter the number. 10
99
Can't we use pow() function for int data type??
Floating point precision is doing its job here. The actual working of pow is using log
pow(a, 2) ==> exp(log(a) * 2)
Look at math.h library which says:
###<math.h>
/* Excess precision when using a 64-bit mantissa for FPU math ops can
cause unexpected results with some of the MSVCRT math functions. For
example, unless the function return value is stored (truncating to
53-bit mantissa), calls to pow with both x and y as integral values
sometimes produce a non-integral result. ... */
Just add 0.5 to the return value of pow and then convert it to int.
b = (int)(pow(a,2) + 0.5);
So, the answer to your question
Does pow() work for int data type in C?
Not always. For integer exponentiation you could implement your own function (this will work for 0 and +ve exp only):
unsigned uint_pow(unsigned base, unsigned exp)
{
unsigned result = 1;
while (exp)
{
if (exp % 2)
result *= base;
exp /= 2;
base *= base;
}
return result;
}
there is no int based pow. What you are suffering from is floating point truncation.
an int based pow is too constrained (the range of inputs would quickly overflow an int). In many cases int based pow, like in your case where its powers of 2 can be done efficiently other ways.
printf("%a", pow(10, 2)) and see what you get; I expect you'll see you don't quite get 100. Call lround if you want to round instead of truncating.
The C library function double pow(double x, double y)
It takes double type

C weird approximation on floating point [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
I have the following code:
#include<stdio.h>
int main(int argc, char const *argv[])
{
float min, max, step;
min = -0.85, max = 0.85, step = 0.002;
int rank = 3, total = 4;
float step1 = min + (max - min) * rank / total; // should be 0.425
printf("%f %.7g\n", step1, step1); // 0.425000 0.4250001
float step2 = min + (max - min) * (rank + 1) / total - step; //should be 0.848
printf("%f %.7g\n", step2, step2); // 0.848000 0.848
float noc = (step2 - step1 + step) / step; //should be 212,5
printf("%f %.7g\n", noc, noc); // 212.499985 212.5
int nol = 1200;
int result = (int)nol * noc; //should be 255000
printf("%d\n", result); // 254999
return 0;
}
This is a fragment of code isolated from a project I have to do. The final result should be 255000, but for some causes, it shows 254999. Can someone please explain me what happens in the process? I have read somewhere that multiplying a floating number with 10^k and then dividing back solves such problems, but in this case, due to the variable step varying from 0.000001 to 0.1, I can't actually use that (in the same way, I can't use a defined EPSILON). What else can I do?
Thanks in advance!
P.S.: I have used double and long double as well, but with same problems, only this time error propagates from a further decimal. I am using gcc 4.8.2, under Ubuntu 14.04.1.
Truncation vs. rounding.
Due to subtle rounding effect of FP arithmetic, the product nol * noc may be slightly less than an integer value. Conversion to int results in fractional truncation. Suggest rounding before conversion to int.
#include <math.h>
int result = (int) roundf(nol * noc);
the significant problem(s) are:
1) mixing floating point and double with integer math
--so the compiler promotes all the math to float (or double)
2) not all numbers can be expressed exactly in float
3) --the initialization of min, max, step are taking double literals
and converting them to float
--even double cannot express all values exactly
--some precision is lost when performing the conversion from double to float
4) this code excerpt: (rank + 1) / total is always = 1
--(although the many conversions may result in being 'not exactly' 1)
5) argc and argv are not referenced in your code.
--this, given that all warnings are enabled, will rise two warnings
at compile time about unused parameters
6) this line in your code is not correct syntax
--(although the compiler might not complain) #include<stdio.h>
--it should be #include <stdio.h>
--sometimes spaces count, sometimes they dont

Why does 1 / 10 equal zero unless I use variables? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can't I return a double from two ints being divided
This statement in C with gcc:
float result = 1 / 10;
Produces the result 0.
But if I define variables a and b with values 1 and 10 respectively and then do:
float result = a / b;
I get the expected answer of 0.1
What gives?
When the / operator is applied to two integers, it's an integer division. So, the result of 1 / 10 is 0.
When the / operator is applied to at least one float variable, it's a float division. The result will be 0.1 as you intend.
Example :
printf("%f\n", 1.0f / 10); /* output : 0.1 (the 'f' means that 1.0 is a float, not a double)*/
printf("%d\n", 1 / 10); /* output : 0 */
Example with variables :
int a = 1, b = 10;
printf("%f\n", (float)a / b); /* output : 0.1 */
That happens because 1 and 10 are integer constants, so the division is done using integer arithmetic.
If at least one of your variables a and b is a float, it will be done using floating-point arithmetic.
If you want to do it with number literals, use the notation to make at least one of them a float literal, for example:
float result = 1.0f / 10;
Or cast one of them to float, that would be a bit more elaborate:
float result = 1 / (float)10;
1 and 10 are both integers and will return an integer, when you define a and b you're defining as a float. If you use 1.0 and 10.0 it will return the correct result
If you want float than just cast it as follow.
float result = (float)a/b;

Resources