AS 中报错:Error:方法 ceil(float) 位置: 类 FloatMath

本文介绍了解决Android Studio中使用过时FloatMath API导致的编译错误的方法。通过将FloatMath替换为标准Math库,可以有效解决此类问题。
Android Studio 中报错:Error:(398, 30) 错误: 找不到符号 符号: 方法 ceil(float) 位置: 类 FloatMath 注: 某些输入文件使用或覆盖了已过时

报错提示:

Android Studio 中报错:
F:\Android\Workspace\NewsApplication\Indicatorlibrary\src\main\java\com\viewpagerindicator\LinePageIndicator.java
Error:(372, 30) 错误: 找不到符号
符号:   方法 ceil(float)
位置: 类 FloatMath
Error:(398, 30) 错误: 找不到符号
符号:   方法 ceil(float)
位置: 类 FloatMath
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
2 个错误
Error:Execution failed for task ':Indicatorlibrary:compileDebugJavaWithJavac'.

分析:

类 FloatMath,此 API 过时了,Android 6.0 不再使用了

解决思路及方案:

把 FloatMath 换成 Math,得到解决
<think>我们之前定义了一个名为`ceil-to-precision`的函数,但用户现在在运行代码时遇到误“no function definition: CEIL-TO-PRECISION”。这个误通常发生在AutoLISP环境中,原因可能是: 1. 函数`ceil-to-precision`没有被定义(即该函数没有被加载到当前图形中)。 2. 函数名拼写误(注意LISP中函数名是区分大小写的,但通常都是大写,不过我们定义的函数名是小写,而AutoLISP在内部会将函数名转换为大写,所以大小写通常不是问题。但这里用户输入的是`CEIL-TO-PRECISION`,而我们定义的函数名是`ceil-to-precision`,在AutoLISP中,它们会被视为相同,因为AutoLISP不区分大小写)。 但是,用户遇到这个误,最可能的原因是函数定义没有被加载到当前图形中。 解决方案: 1. 确保在调用`ceil-to-precision`函数之前,已经定义了这个函数。也就是在运行`c:dlio2`命令之前,需要先运行`ceil-to-precision`函数的定义代码。 2. 将两个函数定义放在同一个.lsp文件中,并一次性加载整个文件。 具体步骤: - 将之前定义的`ceil-to-precision`函数和`c:dlio2`函数放在同一个文件中,然后加载该文件。这样,当文件加载时,两个函数都会被定义。 示例代码结构: ```lisp ;; 自定义向上取整函数 (defun ceil-to-precision (num prec / factor temp) (setq factor (expt 10.0 prec)) (setq temp (* num factor)) (if (> (- temp (fix temp)) 1e-8) (/ (float (1+ (fix temp))) factor) (/ (float (fix temp)) factor) ) ) ;; 定义命令 (defun c:dlio2 (/ ent lenData pt1 pt2 segLen offsetVal) ... ; 这里使用(ceil-to-precision ...)函数 (princ) ) ``` 如果用户已经将两个函数放在同一个文件并加载,那么可能是其他问题,例如: - 函数名拼写误:检查调用时的函数名是否和定义时完全一致(尽管不区分大小写,但要注意连字符的数量和位置)。这里我们定义的函数名是`ceil-to-precision`,调用时应该用相同的名字(注意:在LISP中,函数名中的连字符是允许的,但必须一致)。 但是,从误信息`CEIL-TO-PRECISION`来看,用户调用的是`CEIL-TO-PRECISION`(注意:这里没有连字符,误信息中写的是`CEIL-TO-PRECISION`?)实际上,我们定义的函数名是`ceil-to-precision`,其中有两个连字符(在`ceil`和`to`之间,以及`to`和`precision`之间)。但是观察误信息中的函数名:`CEIL-TO-PRECISION`,它中间只有一个连字符(即`CEIL-TO`和`PRECISION`之间)?这可能是用户输入误。 仔细看:我们定义的函数名是`ceil-to-precision`(三个单词,两个连字符),而误信息中显示的是`CEIL-TO-PRECISION`,这看起来也是三个单词,两个连字符(因为`CEIL-TO`和`TO-PRECISION`之间没有连字符,所以实际上误信息中的函数名是`CEIL-TO-PRECISION`,即中间是一个连字符连接三个词?)。实际上,在误信息中,函数名被转换成了大写,并且连字符保留。所以,如果定义时是`ceil-to-precision`,那么转换成大写就是`CEIL-TO-PRECISION`。因此,函数名是一致的。 所以,问题可能在于函数定义没有被加载。 如何解决? - 如果用户将两个函数定义放在同一个文件并加载,那么应该可以解决。 - 如果用户是分开加载的,需要确保先加载`ceil-to-precision`函数,再加载`c:dlio2`函数。 另外,还有一种可能是函数定义有语法误,导致加载失败,从而函数未被定义。因此,在加载文件时,应该检查是否有其他误。 如果用户不想每次都加载整个文件,也可以将`ceil-to-precision`函数定义嵌入到`c:dlio2`函数内部(作为局部函数),但这样会使得代码结构不够清晰,而且每次调用命令都会重新定义(虽然不会出,但没必要)。 另一种方法:将`ceil-to-precision`定义为`c:dlio2`内部的局部函数,使用`defun-q`或嵌套`defun`?在AutoLISP中,可以在一个函数内部定义另一个函数,但这样定义的是局部函数,只能在该函数内部调用。 示例: ```lisp (defun c:dlio2 (/ ceil-to-precision ...) ;; 局部定义向上取整函数 (defun ceil-to-precision (num prec / factor temp) ... ; 函数体 ) ... ; 命令的其他部分 (setq offsetVal (ceil-to-precision ...)) ... ) ``` 这样,当运行`c:dlio2`命令时,会先定义局部函数,然后调用它。这样确保函数一定被定义,且不会污染全局命名空间。 但是,如果用户已经在其他位置定义了同名的全局函数,则可能会被覆盖(但在这个命令执行期间,使用的是局部定义)。不过,由于这个函数只在这个命令中使用,局部定义是合理的。 因此,我们提供两种解决方案: 方案一(推荐):将两个函数定义放在同一个文件中,并确保加载该文件。 方案二:将`ceil-to-precision`函数作为`c:dlio2`的局部函数(嵌套定义)。 下面我们按照方案二修改代码: ```lisp (defun c:dlio2 (/ ent lenData pt1 pt2 segLen offsetVal) ;; 局部定义向上取整函数 (defun ceil-to-precision (num prec / factor temp) (setq factor (expt 10.0 prec)) (setq temp (* num factor)) (if (> (- temp (fix temp)) 1e-8) (/ (float (1+ (fix temp))) factor) (/ (float (fix temp)) factor) ) ) (princ "\n启动测量工具(dlio): 选择线段") (setq ent (car (entsel))) ; 选择对象 ; 验证选择对象 (cond ((null ent) (alert ": 未选择对象") (exit)) ((/= "LINE" (cdr (assoc 0 (entget ent)))) (alert ": 请选择直线对象") (exit)) ) ; 获取线段数据 (setq lenData (entget ent)) (setq pt1 (cdr (assoc 10 lenData)) pt2 (cdr (assoc 11 lenData)) segLen (distance pt1 pt2) ; 使用自定义函数向上取整: $\lceil segLen/3 \rceil$ offsetVal (ceil-to-precision (/ segLen 3.0) 2) ) ; 执行偏移命令 (command "._offset" offsetVal ent "") (princ) ; 静默退出 ) ``` 这样,当用户调用`c:dlio2`命令时,会先定义局部函数`ceil-to-precision`,然后使用它,从而避免未定义误。 注意:嵌套定义的函数只在主函数执行期间有效,并且不会与其他同名全局函数冲突(因为局部定义会覆盖全局定义,但只在主函数内部)。 如果用户希望多次使用这个取整函数,并且在其他命令中也使用,那么应该采用全局定义,并确保在使用前加载。 相关问题: 1. 如何将LISP函数定义在另一个函数内部? 2. AutoLISP中局部函数和全局函数的区别? 3. 如何避免AutoLISP中的函数未定义误? </think> ### 解决 AutoCAD LISP 中 "no function definition: CEIL-TO-PRECISION" 误 #### 误原因分析 该误表示 AutoLISP 解释器找不到 `CEIL-TO-PRECISION` 函数的定义,通常由以下原因导致: 1. **函数未定义**:未在代码中声明该函数 2. **作用域问题**:函数定义在调用之后 3. **文件加载顺序误**:包含函数定义的文件未正确加载 4. **拼写误**:函数名大小写或拼写不一致(AutoLISP 函数名不区分大小写) --- ### 解决方案 #### 方法 1:添加函数定义(推荐) 在调用 `CEIL-TO-PRECISION` 前添加完整函数定义: ```lisp ;; 自定义向上取整函数 (必须定义在调用之前) (defun ceil-to-precision (num prec / factor temp) (setq factor (expt 10.0 prec)) ; $factor = 10^{prec}$ (setq temp (* num factor)) ; $temp = num \times factor$ (if (> (- temp (fix temp)) 1e-8) ; 浮点容差处理 (/ (float (1+ (fix temp))) factor) ; 向上进位 (/ (float (fix temp)) factor) ; 整数部分 ) ) ;; 主命令 (defun c:your-command () (setq val (ceil-to-precision 5.333 2)) ; 调用示例 (princ val) ) ``` #### 方法 2:使用全局加载 创建独立 LISP 文件 `math-utils.lsp`: ```lisp ;; math-utils.lsp (defun ceil-to-precision (num prec / factor temp) (setq factor (expt 10.0 prec)) ... ; 完整函数体 ) ``` 在启动时自动加载: ```lisp ;; 添加到acaddoc.lsp (load "C:/path/to/math-utils.lsp") ``` #### 方法 3:内联简化实现 如果只需基本功能,可直接内联数学计算: ```lisp (defun c:your-command () (setq num 5.333) (setq prec 2) (setq result (/ (float (fix (+ (* num (expt 10.0 prec)) 0.999999))) (expt 10.0 prec))) (princ result) ) ``` --- ### 关键注意事项 1. **定义顺序**:函数必须定义在调用之前 2. **浮点精度**:使用 `1e-8` 容差避免计算误差 3. **作用域**:使用 `/` 声明局部变量防止污染全局命名空间 4. **调试技巧**:用 `(type 'ceil-to-precision)` 验证函数是否定义 --- ### 数学原理 向上取整公式实现: $$\text{ceil}(x,p) = \frac{\lfloor x \cdot 10^{p} + 0.999... \rfloor}{10^{p}}$$ 其中: - $x$:原始数值 - $p$:精度(小数位数) - $\lfloor \cdot \rfloor$:向下取整函数[^1] --- ### 相关问题 1. **如何实现向下取整(FLOOR)功能?** 修改判断逻辑:`(if (> (- temp (fix temp)) 1e-8) ...)` → 直接返回截断值 2. **AutoLISP 中如何检测函数是否已定义?** 使用 `(type 'function-name)` 返回 `SUBR` 表示已定义,`nil` 表示未定义 3. **为什么需要浮点容差 1e-8?** 计算机二进制浮点计算存在精度误差(如 0.1+0.2≠0.3),容差值避免误判[^3] 4. **如何批量管理自定义函数库?** 创建 `my-lib.lsp` 集中存储工具函数,通过 `(load "my-lib")` 加载 5. **四舍五入与向上取整有何区别?** 四舍五入遵循"5入"规则,向上取整总是向正无穷方向取整: - 四舍五入:`(rtos 2.5 2 0) → "3"` - 向上取整:`(ceil-to-precision 2.5 0) → 3.0` - 向下取整:`(fix 2.5) → 2` [^1]: Math.ceil() 的向上取整逻辑参考 [^3]: 浮点精度处理是函数式编程的关键挑战 [^4]: 函数作用域管理对避免未定义误至关重要
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值