在度和毫秒之间转换 [英] Convert between Degree and Milliseconds

查看:245
本文介绍了在度和毫秒之间转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道从度到毫秒转换的公式,反之亦然.可以这样实现:

 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;
    }

方案:我从度转换为毫秒,然后继续从毫秒转换为度.转换后的值与原始值有一些差异.我希望该值也与原始值一样准确.例如:

$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)

还有一种减少差异的方法是度和毫秒之间的转换吗?

解决方案

有360度(经度),每度60分钟,每分钟60秒,每秒1000毫秒.所以至多

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

这非常适合31位,因此我们的想法是先转换为整数,然后以整数形式执行尽可能多的操作.

请注意,如果您使用单精度浮点,则将获得24位有效数字,并且精度会在1十分之一秒以内下降(log2(360*60*60*10)大约为23.6).

我建议以双精度(53位有效)存储结果.

编辑

我建议的是一次转换,如果有一种方法可以使用双精度来表示$decimaldegrees(我不太了解php),就像这样:

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

然后,如果您想分解为DMS(但是在您的代码中未使用这些变量):

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

再深入了解一下您的代码,看来您是先分隔小数部分$tempma = "0.".$vars[1];
如果您使用十进制表示形式的字符串,这可能会起作用,因为在这种情况下,即使在单精度浮点数(log2(60*60*1000)大约为21.8)上也很合适.因此开始可以替换为:

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

在您给出的输出示例中,听起来问题出在另一个转换milisecond_to_decimal上,大概是因为某些算术运算是使用整数算术执行的,因此会丢弃毫秒.

再一次,我对php的了解还不够多,但是$s = $s % 3600;实际上不会在(int)(%s)上运行并因此放弃毫秒吗?
您将需要找到与C函数fmodmodf等效的东西.

再一次,如果可以采用双精度方式,您可以一次执行所有操作:

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

如果您无法使用双精度,则无法安全地进行重构,单精度没有足够的位数...

您将需要在单独的弦乐部分上进行操作,照顾小数部分中的前导零

无论如何,我强烈建议执行单元测试,即分别测试您的两个功能,这样您将更好地了解哪些有效,哪些无效.

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?

解决方案

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.

这篇关于在度和毫秒之间转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆