is there a simple way to round the result of a division to upper integer ?
I would like to have this :
18/20 -> 1
19/20 -> 1
20/20 -> 1
21/20 -> 2
22/20 -> 2
23/20 -> 2
... and so on ...
38/20 -> 2
39/20 -> 2
40/20 -> 2
41/20 -> 3
42/20 -> 3
43/20 -> 3
Must I manager with NSNumberFormatter stuff ?
I didn't success to get an integer value with that and have an integer comparison to do.
Thanks in advance !
int x, y;
int result = (x + (y-1)) / y;
testing:
int n = 20;
for (int i = 1; i <= 50; i++) {
NSLog(#"%d+(%d-1) / %d = %d", i, n, n, (i+(n-1))/n);
}
You use the standard ceil() and ceilf() functions available i math.h
Standard C supports double ceil(double x) and long double ceill(long double x). Perhaps the iPhone has these available? If your data is in integers in the first place, then you'll either have to find a clever trick or convert your ints to doubles first.
NSNumberFormatter is used when converting between numbers and strings. In addition to the c functions on primitives mentioned already, you can use NSDecimalNumber and NSDecimalNumberHandler to perform the calculation and rounding given instances of NSNumber. When in doubt, refer to the documentation. Number and Value Programming Guide
Sample code to divide, round up to the next integer and display the result.
NSDecimalNumber *denominator = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:20] decimalValue]];
NSDecimalNumberHandler *numberHandler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
for (NSInteger counter = 1; counter <= 50; counter++) {
NSDecimalNumber *numerator = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:counter] decimalValue]];
NSDecimalNumber *result = [[numerator decimalNumberByDividingBy:denominator withBehavior:numberHandler] retain];
NSLog(#"%#/%# -> %d", numerator, denominator, [result integerValue]);
[result release];
}
Related
I worked a lot in it and can't find a solution. Even the title can't explain clearly.
I have three values weight, quantity and total
I had done the following
float wq = [[weightarray objectAtIndex:selectedint]floatValue];
float q = [quantity floatValue];
float total = wq * q;
for ex, if
[weightarray objectAtIndex:selectedint] = #"3.14";
quantity = 4;
then the result is
wq = 3.140000 q= 4.000000 total = 12.560000
but I need
wq = 3.14 total = 12.56
what to do?
I searched a lot, someone suggests to use NSDecimal,
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE];
but the scale is not 2 here, wq value may have 3 or four numbers after point.
If the total = 2.30000100 means I need total = 2.300001
how to solve this?
I'm not entirely sure what it is your asking for, but it seems as if you want the values to only display a 2 d.p. In which case you could use a string format like so:
NSString *output = [NSString stringWithFormat:#"float = %.2f", 3.14];
The .2 specifies that the float should be justified to 2 d.p.
Hope this helps
There may be a more direct way to achieve it (which I don't know) but here's a suggestion...
Convert to string as you already do.
Use [myString hasSuffix:#"0"] to see if it ends in zero.
Use [myString substringToindex:[myString length]-1] to create a new string without the final zero.
Repeat.
I know it's not elegant, but unless someone has a better solution, this will at least do what you want.
UPDATE: scratch that - I just discovered [myString stringByTrimmingCharactersInSet:set]. Surely this must be what you need...?
Finally solution found, thanks to Martin
float total = 12.56000;
NSString *s = [NSString stringWithFormat:#"%f", total];
NSLog(#"%#",s);
BOOL success;
success =NO;
while(!success)
{
if ([s hasSuffix:#"0"])
{
s = [s substringWithRange:NSMakeRange(0,[s length]-1)];
}
else if ([s hasSuffix:#"."])
{
s = [s substringWithRange:NSMakeRange(0,[s length]-1)];
success = YES;
}
else
success = YES;
}
NSLog(#"%#",s);
if total = 12.560000 it returns total = 12.56
if total = 12.000000 it returns total = 12
if total = 10.000000 it returns total = 10
if total = 12.3000100 it returns total = 12.30001
guys, I'm making simple graph drawer and want to find beautiful values for horizontal lines.
For example, if I have value equals to 72089.601562, beautiful is 70000, or 75000. So, I think that beautifulNumber%5 = 0.
Have you any ideas?
How about this?
#import <math.h>
#import <stdio.h>
#define ROUNDING 5000
int beautify(float input)
{
// Cast to int, losing the decimal value.
int value = (int)input;
value = (value / ROUNDING) * ROUNDING;
if ((int)input % ROUNDING > ROUNDING / 2 )
{
value += ROUNDING;
}
return value;
}
int main()
{
printf("%d\n", beautify(70000.601562)); // 70000
printf("%d\n", beautify(72089.601562)); // 70000
printf("%d\n", beautify(76089.601562)); // 75000
printf("%d\n", beautify(79089.601562)); // 80000
printf("%d\n", beautify(70000.601562)); // 70000
return 0;
}
It depends whether you want a floor value, a ceiling value or just to round to the nearest 5000.
For a floor value:
int beautiful = (int)(floor(ugly / 5000.0) * 5000.0);
For a ceiling value:
int beautiful = (int)(ceil(ugly / 5000.0) * 5000.0);
For rounding:
int beautiful = (int)(round(ugly / 5000.0) * 5000.0);
For making graph lines, I'd probably find the minimum and maximum values you have to graph, start with a floor value for the minimum value and then add your desired interval until you have surpassed your maximum value.
For instance:
float minValue = 2.34;
float maxValue = 7.72;
int interval = 1;
NSMutableArray *horizLines = [NSMutableArray array];
int line = (int)(floor(minValue / interval) * interval);
[horizLines addObject:[NSNumber numberWithInt:line]];
do {
line = (int)(ceil(minValue / interval) * interval);
[horizLines addObject:[NSNumber numberWithInt:line]];
if (minValue >= maxValue) break;
minValue = minValue + interval;
}
Use as needed!
Well, it seems like you'd want it to scale based on the size of the number. If the range only goes to 10, then obviously rounding to the nearest 5,000 doesn't make sense. There's probably a really elegant way to code it using bit shifting but just something like this will do the trick:
float value = 72089.601562
int beautiful = 0;
// EDIT to support returning a float for small numbers:
if (value < 0.2) beautiful = int(value*100)/100.;
else if (value < 2.) beautiful = int(value*10)/10.;
// Anything bigger is easy:
else if (value < 20) beautiful = (int)value;
else if (value < 200) beautiful = (int)value/10;
else if (value < 2000) beautiful = (int)value/100;
else if (value < 20000) beautiful = (int)value/1000;
// etc
Sounds like what you want to do is round to 1 or perhaps 2 significant digits. Rounding to n significant digits is pretty easy:
double roundToNDigits(double x, int n) {
double basis = pow(10.0, floor(log10(x)) - (n-1));
return basis * round(x / basis);
}
This will give you roundToNDigits(74518.7, 1) == 70000.0 and roundToNDigits(7628.54, 1) == 8000.00
If you want to round to 1 or 2 digits (only 2 where the second digit is 5), you want something like:
double roundSpecial(double x) {
double basis = pow(10.0, floor(log10(x))) / 2.0;
return basis * round(x / basis);
}
Okay so I'm trying to get my values rounded up to the nearest whole number with an IBAction.
So 1.88 -> 2.00 ,
11.40 -> 12.00 ,
111.01 -> 112.00, etc.
-
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=lblTotalRound.text floatValue];
ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
That's what I got. But it's still rounding down below .5 and to the nearest integer
(Ex. 1.19 -> 1 , i need 1.19 -> 2.00).
I've tried %1.2f but the value doesnt change at all.
What am I doing wrong?
ceilf doesn't modify the value you pass in. It returns a modified value.
floatRoundValue = ceilf(floatRoundValue);
ceilf is a function that returns a value (https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/ceil.3.html) , you simply need to change that line to the following.
floatRoundValue = ceilf(floatRoundValue);
So the complete code would in your case it would be something like this.
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=lblTotalRound.text floatValue];
floatRoundValue = ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
If you need to have a $ sign before :
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=(lblTotalRound.text floatValue];
floatRoundValue = ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"$%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
NSString Class Reference
I want to convert decimal number in binary number. I'm using this method:
- (NSMutableString*)intStringToBinary:(long long)element{
NSMutableString *str = [[NSMutableString alloc] initWithString:#""];
for(NSInteger numberCopy = element; numberCopy > 0; numberCopy >>= 1)
{
[str insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
}
return str;
}
everything is going fine if the number "element" is >0. If the number is <0 there is the problem. For examle the method can't convert the number "-1". What can i do to solve the problem? Thanks in advance!!
You need an extra bit for the sign.
Example:
1xxxx represents the binary number + xxxx.
0yyyy represents the binary number - yyyy.
Here is a way to do it in Python using Wallar's Algorithm. The input and output are lists.
from math import *
def baseExpansion(n,c,b):
j = 0
base10 = sum([pow(c,len(n)-k-1)*n[k] for k in range(0,len(n))])
while floor(base10/pow(b,j)) != 0: j = j+1
return [floor(base10/pow(b,j-p)) % b for p in range(1,j+1)]
I want to check if a floating point value is "nearly" a multiple of 32. E.g. 64.1 is "nearly" divisible by 32, and so is 63.9.
Right now I'm doing this:
#define NEARLY_DIVISIBLE 0.1f
float offset = fmodf( val, 32.0f ) ;
if( offset < NEARLY_DIVISIBLE )
{
// its near from above
}
// if it was 63.9, then the remainder would be large, so add some then and check again
else if( fmodf( val + 2*NEARLY_DIVISIBLE, 32.0f ) < NEARLY_DIVISIBLE )
{
// its near from below
}
Got a better way to do this?
well, you could cut out the second fmodf by just subtracting 32 one more time to get the mod from below.
if( offset < NEARLY_DIVISIBLE )
{
// it's near from above
}
else if( offset-32.0f>-1*NEARLY_DIVISIBLE)
{
// it's near from below
}
In a standard-compliant C implementation, one would use the remainder function instead of fmod:
#define NEARLY_DIVISIBLE 0.1f
float offset = remainderf(val, 32.0f);
if (fabsf(offset) < NEARLY_DIVISIBLE) {
// Stuff
}
If one is on a non-compliant platform (MSVC++, for example), then remainder isn't available, sadly. I think that fastmultiplication's answer is quite reasonable in that case.
You mention that you have to test near-divisibility with 32. The following theory ought to hold true for near-divisibility testing against powers of two:
#define THRESHOLD 0.11
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 31) && (l2 & 31 ? 1 : f - (float) l2 <= THRESHOLD);
}
What we're doing is coercing the float, and float + THRESHOLD to long.
f (long) f (long) (f + THRESHOLD)
63.9 63 64
64 64 64
64.1 64 64
Now we test if (long) f is divisible with 32. Just check the lower five bits, if they are all set to zero, the number is divisible by 32. This leads to a series of false positives: 64.2 to 64.8, when converted to long, are also 64, and would pass the first test. So, we check if the difference between their truncated form and f is less than or equal to THRESHOLD.
This, too, has a problem: f - (float) l2 <= THRESHOLD would hold true for 64 and 64.1, but not for 63.9. So, we add an exception for numbers less than 64 (which, when incremented by THRESHOLD and subsequently coerced to long -- note that the test under discussion has to be inclusive with the first test -- is divisible by 32), by specifying that the lower 5 bits are not zero. This will hold true for 63 (1000000 - 1 == 1 11111).
A combination of these three tests would indicate whether the number is divisible by 32 or not. I hope this is clear, please forgive my weird English.
I just tested the extensibility to other powers of three -- the following program prints numbers between 383.5 and 388.4 that are divisible by 128.
#include <stdio.h>
#define THRESHOLD 0.11
int main(void) {
int nearly_divisible(float);
int i;
float f = 383.5;
for (i=0; i<50; i++) {
printf("%6.1f %s\n", f, (nearly_divisible(f) ? "true" : "false"));
f += 0.1;
}
return 0;
}
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 127) && (l2 & 127 ? 1 : f - (float) l2 <= THRESHOLD);
}
Seems to work well so far!
I think it's right:
bool nearlyDivisible(float num,float div){
float f = num % div;
if(f>div/2.0f){
f=f-div;
}
f=f>0?f:0.0f-f;
return f<0.1f;
}
For what I gather you want to detect if a number is nearly divisible by other, right?
I'd do something like this:
#define NEARLY_DIVISIBLE 0.1f
bool IsNearlyDivisible(float n1, float n2)
{
float remainder = (fmodf(n1, n2) / n2);
remainder = remainder < 0f ? -remainder : remainder;
remainder = remainder > 0.5f ? 1 - remainder : remainder;
return (remainder <= NEARLY_DIVISIBLE);
}
Why wouldn't you just divide by 32, then round and take the difference between the rounded number and the actual result?
Something like (forgive the untested/pseudo code, no time to lookup):
#define NEARLY_DIVISIBLE 0.1f
float result = val / 32.0f;
float nearest_int = nearbyintf(result);
float difference = abs(result - nearest_int);
if( difference < NEARLY_DIVISIBLE )
{
// It's nearly divisible
}
If you still wanted to do checks from above and below, you could remove the abs, and check to see if the difference is >0 or <0.
This is without uing the fmodf twice.
int main(void)
{
#define NEARLY_DIVISIBLE 0.1f
#define DIVISOR 32.0f
#define ARRAY_SIZE 4
double test_var1[ARRAY_SIZE] = {63.9,64.1,65,63.8};
int i = 54;
double rest;
for(i=0;i<ARRAY_SIZE;i++)
{
rest = fmod(test_var1[i] ,DIVISOR);
if(rest < NEARLY_DIVISIBLE)
{
printf("Number %f max %f larger than a factor of the divisor:%f\n",test_var1[i],NEARLY_DIVISIBLE,DIVISOR);
}
else if( -(rest-DIVISOR) < NEARLY_DIVISIBLE)
{
printf("Number %f max %f less than a factor of the divisor:%f\n",test_var1[i],NEARLY_DIVISIBLE,DIVISOR);
}
}
return 0;
}