當前位置: 首頁> 最新文章列表> 為什麼ceil() 和JSON 序列化後結果不同?

為什麼ceil() 和JSON 序列化後結果不同?

M66 2025-06-02

在PHP 開發中,常常會遇到這樣的疑惑:使用ceil()函數得到的結果與經過json_encode()序列化後,再解碼的結果看起來不一致。為什麼會出現這種現象?本文將從底層數值表示、JSON 編碼機制等角度來分析原因,並給出相應的示例說明。

1. ceil()函數的作用和返回值

ceil()函數用於向上取整,返回不小於參數的最小整數值。它的返回值類型是浮點數(float),即使結果是整數,返回值仍是浮點型。

 <?php
$num = 4.2;
$result = ceil($num);
var_dump($result); // float(5)
?>

可以看到, ceil()返回的是浮點數5.0 ,而不是整型5

2. 浮點數的二進製表示及精度問題

PHP 中的浮點數基於IEEE 754 雙精度標準,使用64 位二進製表示一個數字。浮點數無法精確表示所有十進制小數,存在精度誤差。

這就導致即使ceil()結果理論上是整數,比如5.0 ,底層二進制存儲中可能會有極小的誤差。

3. JSON 序列化時浮點數的處理

json_encode()會將PHP 的浮點數轉換為JSON 數字類型。 JSON 本身不區分整數和浮點數,只有數字類型。

例如:

 <?php
$num = ceil(4.2);
$json = json_encode($num);
echo $json; // 輸出 "5"
?>

雖然PHP 中$num是浮點數5.0 ,JSON 中表示為數字5 ,去掉了小數點和小數部分。

4. JSON 解析後的類型變化

當你使用json_decode()解析JSON 字符串時,默認會將數字轉換為浮點數或整數,具體取決於JSON 字符串的表現形式。

 <?php
$json = json_encode(ceil(4.2)); // "5"
$decoded = json_decode($json);
var_dump($decoded); // int(5)
?>

這裡, json_decode()將JSON 中的5轉換成了整型int(5) ,與原來PHP 中的浮點數float(5)不同。

5. 結果不同的根本原因

總結來說:

  • ceil()返回的始終是浮點數。

  • json_encode()輸出的數字形式去掉了小數點部分。

  • json_decode()根據數字形式將其轉換成整數或浮點數。

  • 因此, ceil()得到的是浮點數float(5) ,而經過JSON 序列化再解碼後可能變成整數int(5)

這就是為什麼你會看到兩者的結果類型和表現形式不同的原因。

6. 代碼示例演示

<?php
$num = 4.2;
$ceilValue = ceil($num);
echo "ceil() 結果:";
var_dump($ceilValue);  // float(5)

$json = json_encode($ceilValue);
echo "json_encode() 結果: $json\n"; // "5"

$decoded = json_decode($json);
echo "json_decode() 結果:";
var_dump($decoded);  // int(5)
?>

輸出:

 ceil() 結果:float(5)
json_encode() 結果:5
json_decode() 結果:int(5)

7. 解決思路和建議

  • 如果你希望保持ceil()返回值為整數類型,可以在使用後強制類型轉換:

 $intValue = (int)ceil($num);
  • 注意JSON 解析後數字類型的自動轉換,必要時可以開啟第二個參數$assoc = true ,將JSON 轉為關聯數組,更方便處理。

  • 理解浮點數和JSON 數字的差異,避免因類型不同帶來的邏輯錯誤。