Optimization 如何将数字的最后3位转换为0
如何将数字的最后3位转换为0 示例3444678至3444000 我真的很喜欢 (国际)(3444678/1000)*1000=3444000 但除法和乘法可能代价高昂 任何其他解决方案???您可以尝试Optimization 如何将数字的最后3位转换为0,optimization,math,Optimization,Math,如何将数字的最后3位转换为0 示例3444678至3444000 我真的很喜欢 (国际)(3444678/1000)*1000=3444000 但除法和乘法可能代价高昂 任何其他解决方案???您可以尝试 n - (n % 1000) 但模运算符可能与除法一样昂贵。在任何情况下,这听起来非常像一个微观优化。这真的是你的瓶颈吗?inttakeaway(intnum) int takeAway(int num) { for (int i = 1; i =< 3; i++) {
n - (n % 1000)
但模运算符可能与除法一样昂贵。在任何情况下,这听起来非常像一个微观优化。这真的是你的瓶颈吗?inttakeaway(intnum)
int takeAway(int num)
{
for (int i = 1; i =< 3; i++)
{
num = num/10;
}
return num;
}
int addZeroes(int num)
{
for (int i = 1; i =< 3; i++)
{
num = num*10;
}
return num;
}
{
for(int i=1;i=<3;i++)
{
num=num/10;
}
返回num;
}
int addZeroes(int num)
{
for(int i=1;i=<3;i++)
{
num=num*10;
}
返回num;
}
然后你只需要叫外卖然后加零。再简单不过了
我试图添加一个int temp=num,然后使用它,但我认为这太多了,即使对于这段代码也是如此。如果您想要舍入到任意精度,并且您的舍入方法缺少精度控制,那么这应该可以工作: 至少在Perl中,mod应该更快 原因如下: 本基准产生的(10**7)*3个随机浮点数样本:
Dividing
Time taken was 7 wallclock secs ( 6.83 usr 0.00 sys + 0.00 cusr 0.00 csys = 6.83 CPU) seconds
Multiplying
Time taken was 7 wallclock secs ( 6.67 usr 0.00 sys + 0.00 cusr 0.00 csys = 6.67 CPU) seconds
Modding
Time taken was 8 wallclock secs ( 7.87 usr 0.00 sys + 0.00 cusr 0.00 csys = 7.87 CPU) seconds
Multiply + Dividing
Time taken was 10 wallclock secs (10.18 usr 0.01 sys + 0.00 cusr 0.00 csys = 10.19 CPU) seconds
但是请注意,10**7*3
是一个redicle浮点数。我不能使用10**8
浮点,因为为了公平的测试,我必须对所有测试使用相同的浮点序列,而且很多浮点耗尽了我的4G内存
好的,比特侧主题:/
(Perl实现只使用Int,通常是截断而不是舍入)
使用模数法
如上所述(除了不舍入)使用整数的模方法,但仍然适用于舍入到浮点精度(小数点右侧的精度有点慢)
use strict;
use warnings;
use version;
our $VERSION = qv('0.1');
sub xround {
my ( $number, $precision ) = @_;
my $ino = int( $number );
if ( $precision eq 0 ) {
return $ino;
}
my $power = 10**$precision;
if ( $precision > 0 ) {
return int( $number - ( $number % $power ) );
}
return $ino + int( ( $number - $ino ) / $power ) * $power;
}
my $fmt = "%s : %s ( %s )\n";
my $n = 55555.55555;
for my $i ( -4 .. 4 )
{
printf $fmt, $n, xround($n, $i), $i;
}
顺便说一句(你已经在这里得到了很好的输入)
位操作从来都不适用于十进制数。问题是位的值根本不映射到十进制。使用BCD它工作得很好,但从来没有人使用过它(也许BigDecimal会这么做?我对此表示怀疑)
无论如何,你可以使用一个以10为基数的技巧乘以10的因数,但除非你是在1970年代的CPU上编写汇编程序,否则这是不值得的;但仅仅因为它污染了我的内存库,我就把它贴出来供你娱乐:
int mult10(int val) {
int tmp_2val = val << 1; // double val
int tmp_8val = val << 3; // 8x val
return( tmp_2val + tmp_8val ); // 2x + 8x = 10x
}
int mult10(int val){
int tmp_2val=val一个移位技巧,然后:
n >>= 3;
n -= n % (5 * 5 * 5);
n <<= 3;
它乘以某个疯狂的数字(274877907),然后做一些其他的事情,大概更快
这个故事的寓意是:你的代码对编译器的作用越明显,编译器就越有可能以你从未想过的方式对其进行优化。如果代码更容易让人理解,这是另一个好处。如果你在使用八进制,你可以简单地:
x &= ~0777;
x &= ~0xfff;
如果您正在使用十六进制,您可以简单地:
x &= ~0777;
x &= ~0xfff;
但对于decimal,您可能应该按照Jesse Beder的建议进行:
x -= (x % 1000);
大多数系统都有一个快速整数除法;如果你在一个没有除法的系统上工作,你可以使用该算法快速转换为bcd
根据您尝试执行的其他操作,在将数字转换为可打印(字符串)时,截断可能更容易格式如Avitus所建议。不,这不是任何瓶颈。我只是想知道是否有一些位操作技巧可以解决这个问题,比如移位运算符或其他东西。这是一个不错的选择,但我担心它太聪明了。原来的方式更清楚你在做什么。另外,正如你所说的,添加/除法是相同的co实际上,我发现它比原来的更可读(因为这取决于整数的截断,这对我来说总是不明显的),但这是一个品味的问题。无论如何,原始版本实际上是乘法/除法,可能比subtract/mod慢一点。乘法/除法肯定比subtract/mod慢。mod通常使用完全相同的电路实现(通常使用完全相同的指令)作为除法,只使用结果的另一半。倍数当然比减法更复杂。18纳秒的除法?这太过分了!光子可能从我的电脑机箱中、从窗口中出来,然后大部分时间都在前面的花园里!这涉及循环,比做(num/1000)更昂贵*1000讽刺在互联网上不起作用。下次试着用笑脸。:)自然。鉴于每个人都说这很好,我觉得有必要提供一个“替代品”。但它确实起作用!理查德,你是在暗示这不是一个玩笑吗?我现在真的很困惑:-(我投了这个票,因为它可能是这里最好的解决方案。可重用且意图明确。当程序员担心简单除法/乘法的性能时,这不是一个好迹象!这意味着他不明白!如果数字是整数,那么除法和乘法不应该太昂贵。确保它们是整数,并确保我认为,这个部门是一个整数除法。我只能猜测你使用的是什么语言,所以不能对适当的语法提出建议。抱歉,我只是注意到一些有用的人删除了你原来在你的问题中包含的C++标签。我真的不明白为什么人们会做那种编辑。是的,不知道为什么人们会编辑标签。我不认为这应该被允许编辑其他人的内容……我知道这个问题需要一个数学解决方案。然而,一个简单的字符串格式解决方案不是最简单、最明显的吗?有时,在一些边缘情况下,微优化会带来好处。特别是在某些方面。我看到了一个3n+1挑战如果你使用二进制编码十进制(BCD),那么也只有这样你才能在base10中进行位运算:)我在回答中提到了BCD。另外,一个带有数学协处理器的系统也应该这样做
x &= ~0xfff;
x -= (x % 1000);