Convert between Degree and Milliseconds

只谈情不闲聊 提交于 2020-01-03 02:21:14

问题


I know the formular for conversion from Degree to Milliseconds and vice-versa. It can be implemented like that:

 protected function decimal_to_milisecond($dec) {
        if (!empty($dec)) {         
            $vars = explode(".",$dec);
            if (count($vars) == 2) {
                $deg = $vars[0];
                $tempma = "0.".$vars[1];
                $tempma = $tempma * 3600;
                $min = floor($tempma / 60);
                $sec = $tempma - ($min*60);
                return round((((($deg * 60) + $min) * 60 + $sec) * 1000));
            } 
            else return false;
        } else return false;
    }

 function milisecond_to_decimal($sec) {
        if (!empty($sec)) {
            $s = $sec / 1000;
            $d = (int)($s / 3600);
            $s = $s % 3600;
            $m = (int)($s / 60);
            $s %= 60;       
            $ret = substr($d+((($m*60)+($s))/3600),0);
        } else return null;
        return $ret;
    }

Scenario: I convert from Degree to Miliseconds and continue converting from Miliseconds to Degree. The converted value has some difference with original value. I want the value is exact as the orginal value as well. For example:

$lat = "1284146";
$long = "503136198";
$lat1 = milisecond_to_decimal($lat);
$long1 = milisecond_to_decimal($long);

$result1 = decimal_to_milisecond($lat1);
$result2 = decimal_to_milisecond($long1);
var_dump($result1, $result2);

The output is float(1284000) and float(503136000)

Is there another way to reduce difference is caused by conversion between degree and milliseconds?


回答1:


There are 360 degrees (longitude), 60 minutes per degree, 60 secondes per minute, 1000 milliseconds per second. So at most

360*60*60*1000 milliseconds = 1 296 000 000 milliseconds

That fits well on 31 bits, so the idea would be to first convert to an integer, and perform as much operations as possible in integer.

Note that if you use single precision floating point, you'll get a 24 bits significand and will loose accuracy under 1 tenth of second (log2(360*60*60*10) is about 23.6).

I would recommend to store results in double precision (53 bits significand).

EDIT

What I was suggesting is to perform the conversion all at once, if there is a way to use double precision for representing $decimaldegrees (I don't know php enough to tell so), something like:

$millis = (int)( round( $decimaldegrees * (60*60*1000) ) );

Then if ever you want to decompose into DMS (but these variables are not used in your code):

$ms  =  $millis % 1000;
$sec = ($millis / 1000) % 60;
$min = ($millis / (60*1000)) % 60;
$deg = ($millis / (60*60*1000)) % 360;

Ater a deeper look at you code, it seems you are separating the decimal part first $tempma = "0.".$vars[1];
That could work if you work on the decimal representation string, because in this case that fits well even on a single precision float (log2(60*60*1000) is about 21.8). So the beginning could be replaced with:

$deg  = (int) $vars[0];
$frac = "0.".$vars[1];
$millis = (int)( round( $frac * (60*60*1000) ) );
$millis = deg + millis;

From the example of output you gave, it sounds like the problem comes from the other conversion milisecond_to_decimal, presumably because some arithmetic operation is performed with integer arithmetic and thus discards the milliseconds.

Once again, I don't know php enough, but wouldn't $s = $s % 3600; in fact operate on (int)(%s) and thus discard the milliseconds?
You would need to find something equivalent to C function fmod or modf.

Once again, you could do all operation at once if there is a way to do it in double precision:

$decimaldegrees = ((double)($millis)) / (60*60*1000);

If you don't have access to double precision, you can't recompose safely, single precision does not have enough bits...

You would need to operate on separate string parts, caring of leading zeros in fraction part

Anyway, I strongly suggest to perform unit tests, that is to test your two functions separately, this way you'll get a better understanding of what works and what not.



来源:https://stackoverflow.com/questions/17311316/convert-between-degree-and-milliseconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!