秋枫 发表于 2010-6-28 14:25:00

[原创][函数]四舍五入到具体的有效位数

在有些情况下,可能需要舍入一个值,到具体位数的有效数字。例如,也许希望这样表述1432187这个值,只保留两个有效数字(这就是变成1400000)。值9187877表述成保留三个有效数字,成为9180000。



(defun std-fraction (num)
(- num (fix num))
)
(defun std-round (num)
(if (>= (abs (std-fraction num)) 0.5)
    (if (minusp num)
      (1- (fix num))
      (1+ (fix num))
    )
    (fix num)
)
)
(defun round (num n)
(/ (std-round (* num (expt 10.0 n))) (expt 10.0 n))
)
(defun std-floor (num)
(if (minusp num)
    (1- (fix num))
    (fix num)
)
)
;; 有效位数取整
(defun RoundDigits(num i)
(round num (- i 1.0 (std-floor (/ (log (abs num)) (log 10.0)))))
)


测试

_$ (rtos (rounddigits 34564.3442 2))
"35000.0000"
_$ (rtos (rounddigits 0.345643442 2))
"0.3500"
_$ (rtos (rounddigits 345643.442 4))
"345600.0000"
_$ (rtos (rounddigits 345643.442 5))
"345640.0000"
_$ (rtos (rounddigits -345643.442 5))
"-345640.0000"
_$ (rtos (rounddigits -345643.442 3))
"-346000.0000"
_$ (rtos (rounddigits -345643.442 9))
"-345643.4420"
_$ (rtos (rounddigits -345643.442 8))
"-345643.4400"
_$ (rtos (rounddigits -345643.442 7))
"-345643.4000"

yaojing38 发表于 2023-6-7 11:15:21

谢谢大神们的分享

szmaicy 发表于 2010-6-29 13:38:00

<font style="BACKGROUND-COLOR: #ffffff" face="Verdana">(defun RoundDigits (num i / a)<br/>&nbsp;&nbsp; (setq a (expt 10.0 i)<br/>&nbsp;&nbsp; num (/ (fix (+ (* num a) 0.5)) a)<br/>&nbsp;&nbsp; )<br/>)</font>

秋枫 发表于 2010-6-29 14:34:00

本帖最后由 作者 于 2010-6-29 15:05:12 编辑 <br /><br /> <p>2楼的,顶楼是“有效数字”, 不是到指定数量级。</p>
szmaicy发表于2010-6-29 13:38:00static/image/common/back.gif(defun RoundDigits (num i / a)&nbsp;&nbsp; (setq a (expt 10.0 i)&nbsp;&nbsp; num (/ (fix (+ (* num a) 0.5)) a)&nbsp;&nbsp; ))

秋枫 发表于 2010-6-29 14:54:00

<p>我说明一下:</p>
<p>&nbsp;</p>
<div>RoundDigits用于我的批量打印程序中忽略图框比例的微小误差。<br/>比如:&nbsp;1:14999&nbsp;-》1:15000;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1:14.9999-》1:15;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1:2500000.12-》1:2500000<br/>2498.798:1&nbsp;-》&nbsp;2500:1<br/></div>
<div>这种情况,不能固定舍入到第几位。<br/></div>
<div>2498.798:1&nbsp;和&nbsp;4.98566:1&nbsp;舍到两位有效数字的话,需要&nbsp;2498.798-》2500,&nbsp;4.98566-》5.0<br/>就是保留几位有效数字的问题。<br/></div>
<div>我Google了一下,关于有人提问怎样设计这样一下保留几位有效数字的函数,N多人都是你这样答非所问的。</div>
<div><br/>正确的应该是这样:<br/>_$&nbsp;(roundDigits&nbsp;2498.798&nbsp;2)<br/>2500.0<br/>_$&nbsp;(roundDigits&nbsp;2498.798&nbsp;3)<br/>2500.0<br/>_$&nbsp;(roundDigits&nbsp;4.98566&nbsp;3)<br/>4.99<br/>_$&nbsp;(roundDigits&nbsp;4.98566&nbsp;2)<br/>5.0<br/></div>
<div>第二个参数表示取整到多少个有效数字。<br/></div>

秋枫 发表于 2010-6-29 14:59:00

<div>问:</div>
<div><br/>_$&nbsp;(roundDigits&nbsp;2498.798&nbsp;2)<br/>2500.0<br/>_$&nbsp;(roundDigits&nbsp;2498.798&nbsp;3)<br/>2500.0&nbsp;<br/></div>
<div>2和3,乍是一样的结果?&nbsp;<br/></div>
<div>&nbsp;</div>
<div>答:</div>
<div><br/>显然是一样的。<br/></div>
<div>2498.798&nbsp;取整到2位有效数字和3位有效数字在数值上是一样的。<br/>一个是&nbsp;2.5X10^3,&nbsp;第一个是&nbsp;2.50X10^3,&nbsp;它们在数值上是相同的。<br/></div>

狂刀lxx 发表于 2010-6-29 16:13:00

一个用于修改特定块属性的程序

貌似这样也差不多哈,写的这么短以至于我都怀疑写错了,帮验证一下

(defun rds (v f) ;; by lxx.2010.6
(distof (rtos v 1 (- f 1)))
)
_$ (rds 2498.798 2)
2500.0
_$ (rds 2498.798 3)
2500.0
_$ (rds 4.98566 3)
4.99
_$ (rds 4.98566 2)
5.0

秋枫 发表于 2010-6-29 16:44:00

<p>狂刀的高!哈哈。</p>

秋枫 发表于 2010-6-29 16:57:00

就用这个了,哈。


(defun RoundDigits (v f) (distof (rtos v 1 (1- f ))))

yunlong300 发表于 2010-7-4 15:33:00

<p>狂刀的高,顶一个:)</p>

wowan1314 发表于 2012-5-1 14:02:48

收藏下! 谢谢分享!
页: [1] 2
查看完整版本: [原创][函数]四舍五入到具体的有效位数