PHP中如何截断数字至第一个非零小数位?round()函数无效
PHP 数字自定义格式化实现
根据你的例子,转换规则可总结为:
- 数字小于1时:保留到第一个非零数字的位置,后续数字直接截断(不四舍五入)
- 数字大于等于1时:找到小数点后第一个非零数字的位置,保留到该位置,后续数字截断
以下是实现该逻辑的PHP函数:
function customFormatNumber($num) { // 处理科学计数法,转成普通十进制字符串 $strNum = (string)$num; if (strpos($strNum, 'E') !== false) { $strNum = sprintf("%.20f", $num); // 去除末尾多余的零和小数点 $strNum = rtrim($strNum, '0'); $strNum = rtrim($strNum, '.'); } // 分割整数和小数部分 $parts = explode('.', $strNum); $integerPart = $parts[0] ?? '0'; $decimalPart = $parts[1] ?? ''; if ($integerPart === '0') { // 处理小于1的数字:计算需要保留的小数位数(前置零的个数 + 1) $leadingZerosCount = strspn($decimalPart, '0'); $decimalPlaces = $leadingZerosCount + 1; // 截断到指定小数位(不四舍五入) $formatted = floor($num * pow(10, $decimalPlaces)) / pow(10, $decimalPlaces); // 格式化字符串,确保保留前置零 $formatted = sprintf("%." . $decimalPlaces . "f", $formatted); } else { // 处理大于等于1的数字:找到小数部分第一个非零的位置 $firstNonZeroPos = strspn($decimalPart, '0'); if ($firstNonZeroPos === strlen($decimalPart)) { // 小数部分全为零,直接返回整数 $formatted = $integerPart; } else { $decimalPlaces = $firstNonZeroPos + 1; // 截断到指定小数位 $formatted = floor($num * pow(10, $decimalPlaces)) / pow(10, $decimalPlaces); // 去除末尾多余的零和小数点 $formatted = rtrim(sprintf("%." . $decimalPlaces . "f", $formatted), '0'); $formatted = rtrim($formatted, '.'); } } return $formatted; }
测试你的示例:
echo customFormatNumber(0.00004123456); // 输出:0.00004 echo customFormatNumber(0.000000004123456); // 输出:0.000000004 echo customFormatNumber(2.04123456); // 输出:2.04 echo customFormatNumber(2.44123456); // 输出:2.4
关键说明:
- 科学计数法处理:避免极小数字被PHP自动转为科学计数法导致逻辑错误
- 截断而非四舍五入:使用
floor()(正数场景)实现直接截断,完全匹配你的示例需求 - 格式补全:通过
sprintf()确保前置零不会丢失,保证输出格式和示例一致
内容的提问来源于stack exchange,提问作者Meysam Zabet
相关产品推荐
相关产品推荐

