【问题标题】:Round to "beautiful" value四舍五入到“美丽”的价值
【发布时间】:2012-04-29 21:19:26
【问题描述】:

伙计们,我正在制作简单的绘图抽屉,并想为水平线找到漂亮的值。 例如,如果我的值等于 72089.601562,则 beautiful 是 70000,或 75000。所以,我认为 beautifulNumber%5 = 0。 你有什么想法吗?

【问题讨论】:

  • 您要四舍五入到最接近的第 5,000 位吗?
  • Methinks NSNumberFormatter 会起作用。
  • 舍入应该是动态的。例如 7 应该转换为 10。
  • “动态”是什么意思?

标签: iphone ios xcode floating-point int


【解决方案1】:

这个怎么样?

#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;
}

【讨论】:

  • 是的。 beatify 函数是纯 C 语言,可以在 Objective-C 项目中使用。请记住,Objective-C 只是添加了一些内容的 C。如果你愿意,你可以把它变成一个 Obj-C 方法,但实际上没有必要。您可以将其保留为 C 函数,只需将其放在您的类之外。
【解决方案2】:

这取决于您是想要一个底值、一个上限还是只是四舍五入到最接近的 5000。

对于底价:

int beautiful = (int)(floor(ugly / 5000.0) * 5000.0);

对于一个上限:

int beautiful = (int)(ceil(ugly / 5000.0) * 5000.0);

四舍五入:

int beautiful = (int)(round(ugly / 5000.0) * 5000.0);

为了制作图表线,我可能会找到您必须绘制的最小值和最大值,从最小值的底值开始,然后添加所需的间隔,直到超过最大值。

例如:

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;
} 

根据需要使用!

【讨论】:

  • 如果丑数是0.3,例如,它会工作吗?我认为,没有。
  • “行不通”是什么意思?在您的示例中,您谈论的是四舍五入 5000,这就是他的示例所做的。
  • 我想要对所有数字进行动态舍入。从 0.0000000003 到 99999
  • 这个请求有问题:它太开放了。你想要线性图还是对数图?如果你的最小值是 0.0004 而你的最大值是 9999 怎么办?哪一个用于创建美丽的间隔?我们可以假设你想要“最近的 5”,不管精度是多少?而且,您是否只想要某个数字上方和下方的“最近的 5”,或者,正如您的问题所述,您是在绘制表示多个值的图形值吗?
  • 我很高兴美丽不是主观的东西,这让它变得容易多了!对于最漂亮的舍入,只需将值转换为 PI。数学家会同意这个值将成为最美丽的值之一!
【解决方案3】:

好吧,您似乎希望它根据数字的大小进行缩放。如果范围仅达到 10,那么显然舍入到最接近的 5,000 是没有意义的。可能有一种非常优雅的方式来使用位移对其进行编码,但只要这样就可以了:

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

【讨论】:

  • 它返回完整的数字,但它应该能被 5 整除,并且您的方法不适用于非常小的数字。例如:0.042。美丽的它:0.05
  • 查看编辑以支持为小数字返回圆形漂亮的浮点数
  • 什么是“完整价值”?
  • 对不起我的英语。完整值是四舍五入的值(round() 函数)。
【解决方案4】:

听起来你想要做的是四舍五入到 1 位或 2 位有效数字。舍入到 n 个有效数字非常简单:

double roundToNDigits(double x, int n) {
    double basis = pow(10.0, floor(log10(x)) - (n-1));
    return basis * round(x / basis);
}

这会给你roundToNDigits(74518.7, 1) == 70000.0和roundToNDigits(7628.54, 1) == 8000.00

如果您想四舍五入到 1 位或 2 位数字(只有 2 位,第二位是 5),您需要类似:

double roundSpecial(double x) {
    double basis = pow(10.0, floor(log10(x))) / 2.0;
    return basis * round(x / basis);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多