2011-07-02 3 views
4

내가 지금처럼 소수점 장소 MB의 형식을, PHP에서 파일 업로드의 크기를 계산하고있다 나는 기대할 것이다. 내가 serialize($metadata)와 배열을 직렬화하고 파일에 저장 때, 출력은 다음과 같습니다PHP의 직렬화() 수에 대한 출력은 꽝

a:2:{s:7:"uploads";i:11;s:11:"upload_data";d:1.6999999999999999555910790149937383830547332763671875;} 

내가 MB에없는 바이트를 파일 크기를 저장하여 효율적으로하기 위해 노력하고있어,하지만이 나쁜 것 같다! 왜 PHP는 그런 식으로 저장합니까? 그리고 나는 이것을 올바른 방향으로 가고 있는가? 수동에서 감사

+4

Dat은 whack fo sho입니다. – Ben

+0

내가 누락 된 것이 있습니까? 바이트로 저장하는 것보다 MB로 저장하는 것이 더 효율적입니까? 그것들은 같은베이스 유닛입니다 ... – rockerest

+0

당신은'json_encode'와'json_decode'를 시도해 볼 수 있습니다. 이것은 (un) serialize보다 빠릅니다. – thetaiko

답변

3

: http://php.net/manual/en/language.types.float.php

는 또한 은 0.1 0.7과 같은 기본 10 부동 소수점 숫자로 정확하게 표현할 수 있다는 합리적 숫자, 부동 소수점 으로 정확한 표현이없는 2 진수는 내부적으로 으로 사용되며 가수의 크기와 상관없이 사용됩니다. 따라서 은 정밀도의 작은 손실없이 내부 바이너리 으로 변환 될 수 없습니다. 혼동 결과가 발생할 수있다 : ((0.1 + 0.7) * 10) 통상 창 (7) 대신에 8 예상한다, 예를 들면, 층 를 내부 표현 되기 때문에 어떤 7.9999999999999991118 등 ....

어레이의 직렬화 버전에서 "1.7"을 보려면 "json_encode"과 "json_decode"을 사용하는 것이 좋습니다. 이 기능들은 또한 serializeunserialize보다 빠르며 읽기 쉽습니다. (읽기 쉽기 때문에, 기계가 아니라 사람이 읽는 것입니다.)

+0

아하! 고마워 친구, 이제 알았어. – Tak

1

serialize의 작동 방식을 전제로합니다.

double (그리고 C가 아닌 다른 언어에서 "float"은 double이 될 것입니다)을 저장하는 확실한 방법은 기본 8 바이트입니다. 내가 아는 한, 대부분의 정상적인 바이너리 직렬화가 이것을 할 것이다.

은 (예, 약간 IEEE 754 64 비트 이진 부동 포인트를 의미하는 "더블"악용하고 있습니다.)

대신, PHP는 사실에 의해 방해되는 소수점 표현을 저장하려고하고있다 바이너리로 정확하게 1.7을 표현할 방법이 없습니다. 가장 가까운 표현은 정확히 1.69999999999999555910790149937383830547332763671875입니다.

필자는 PHP가 왜 똑같은 이중으로 변환하는 가장 짧은 표현 대신에 정확한 표현을 제공하기로 결정했는지 알지 못합니다. (아마도 17 자리 이상은 필요하지 않을 것입니다. 더 짧은 숫자). 한 가지 가능성은 대상 시스템이 다른 부동 소수점 표현을 사용하는 경우 (예 : 대상 시스템이 128 비트 "double-doubles"를 사용하는 경우, 1.7이 다른 수임) 정확한 의미를 보존하려고합니다.

1700은 1.7보다 1 바이트 이상 많지만 정확도는 훨씬 높습니다.

관련 문제