The round function and the 'negative zero.'
Tags: rant, php
Published: 2018-10-30 02:57:38

---
title: The round function and the 'negative zero.'
published: true
description: Me vs. floating point numbers
tags: #rant, #php
---

I wrote this post at qiita.com. I thought I'll share my epic fail here as well.

# Another epic fail I made.

This is a story of me getting mocked by floating point numbers by not reading the document thoroughly. How many times do I have to stress that I should read the docs carefully?!!!??

If you know very well about floating point numbers, you can either skip this post or mock my total idiocy. If you don't know what I'm talking about, this post might help you in the future.

But this is *not* the `0.1 + 0.2 != 0.3` problem.

# Problematic Temperature

I was making a web app where I had to embed some weather forecast using [OpenWeatherMap](https://openweathermap.org/).
[API for OWM](https://openweathermap.org/api) has tons of info, most of which I don't need. I had to make an array containing what I needed. Hopefully, somebody made a wrapper called [OpenWeatherMap-PHP-API](https://github.com/cmfcmf/OpenWeatherMap-PHP-Api).

And some values returned by APIs turned out to be problematic. Below are the samples of data they return.


```JSON
"temp":{
    "day":15.2,
    "min":10.11,
    "max":15.2,
    "night":10.11,
    "eve":15.04,
    "morn":15.2
},
```

I only need `min` and `max.` They stand for 'minimum temp' and 'maximum temp' respectively. When PHP reads this JSON, it stores the values as **`float.`**
Due to space restrictions, I wanted to show them in integers, so I tried rounding them off.

The round function ([`float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )`](https://secure.php.net/manual/en/function.round.php)) was what I needed. This function will round the values off into *integers* ...or so I thought.

# The fail

What will happen if I `round`ed the values above? Let's say we stored the decoded JSON object in `$data.`

```php
round($data['temp']['max']) // => 15
round($data['temp']['min']) // => 10
```

Pretty standard, eh?  
However, I live in a place where it snows in winter. Let's run this code sometime between Autumn and Winter, or between Winter and Spring.

The JSON I'd get looks like this:

```json
"temp":{
    "min":-0.44,
    "max":4.15,
},
```

aaaaaand:

```php
round($data['temp']['max']) // => 4
round($data['temp']['min']) // => -0 <- WTF?
```

# Damnit PHP?
You might have heard about `0.1 + 0.2 != 0.3` in the computer world. The 'glitch' is yet another specification of **floating point numbers.** [^1] [That's how](https://en.wikipedia.org/wiki/Signed_zero) [they work!](https://en.wikipedia.org/wiki/Signed_zero#Scientific_uses)  

[^1]: Yet, PHP output the value that *looks* like an integer which probably confused me. Why is this the case?

Wait, what did [the PHP manual](https://secure.php.net/manual/en/function.round.php) say about the `float` function?

```php
float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
```

float round.

***float.***

*Deal with it m8, it's* ***your*** *epic fail.*

# How I solved it

Since rounded number initially being negative didn't matter for my use case, I cast the return to `int.` (I could've also ditch `round` and directly cast them to `int.`)

```php
(int)round($data['temp']['min']) // => 0
```