nicolasff/phpredis — Issue #61: zAdd and zRangeByScore send different float representations
Author: janoberst
Created: 2011-10-13 14:59:14+00:00
State: open

With certain floats (in my experience microtime timestamps), zAdd and zRangeByScore behave differently. zAdd uses eight decimal places, where zRangeByScore only uses four. With smaller floats both use eight.

Here as an example, the MONITORed commands of the two commands using the same float (1318516439.85713124):

1318517326.022191 "ZADD" "test" "1318516439.85713124" "value1"
1318517326.022665 "ZRANGEBYSCORE" "test" "1318516439.8571" "1318516439.8571"

The zRangeByScore call then returns nothing, because Redis does not think the score is in the range.

I would expect both calls to use the same precision. I can live with standard floating point pains, but they should at least be the same for both calls.

My workaround for now is to cast to string using sprintf.

Example:

```php
connect('localhost');

$score = 1318516439.85713131;
$string_score = sprintf('%.8f', $score);

// add the score (as a float)
echo "adding $score as a float (more exact: $string_score)\n";
$r->zadd('test', $score, 'value1');

// request that very score (as a float)
$result = $r->zrangebyscore('test', $score, $score);
echo "\nrequesting that score as a float:\n";
var_dump($result);

// request that very score (as a string)
$result = $r->zrangebyscore('test', $string_score, $string_score);
echo "\nrequesting that score as a string:\n";
var_dump($result);

// see what redis actually stored
$result = $r->zrange('test', 0, -1, true);
echo "\nredis had stored: {$result['value1']}\n";

?>
```

Output:

adding 1318516439.8571 as a float (more exact: 1318516439.85713124)

requesting that score as a float:
array(0) {
}

requesting that score as a string:
array(1) {
[0]=>
string(6) "value1"
}

redis had stored: 1318516439.8571312