如何在C++中获取17位精度的Julian datetime
问题描述
我正尝试将一段可获取17位精度儒略日期(Julian datetime)的JavaScript代码转换为C++,但C++代码仅能输出整数精度。该17位精度对实时高精度计算天体高度和方位至关重要。
JavaScript代码示例
function JulianDateFromUnixTime(t){ //Not valid for dates before Oct 15, 1582 return (t / 86400000) + 2440587.5; } function setJDToNow(){ const date=new Date(); const jd=JulianDateFromUnixTime(date.getTime()); document.getElementById("jd").value=jd; }
调用后可得到如2459349.210248739的高精度结果。
现有C++代码
#include <chrono> #include <cstdint> #include <iostream> uint64_t timeSinceEpochMillisec() { using namespace std::chrono; return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); } uint64_t JulianDateFromUnixTime(uint64_t t){ //Not valid for dates before Oct 15, 1582 return (t / 86400000) + 2440587.5; } int main() { std::cout << JulianDateFromUnixTime(timeSinceEpochMillisec()) << std::endl; return 0; }
当前输出仅为2459848,完全丢失小数部分精度。
解决方法
问题根源有两点:
- 返回类型错误:
JulianDateFromUnixTime函数返回uint64_t(无符号整数类型),导致计算后的浮点数结果被直接截断为整数,丢失所有小数精度。 - 输出精度不足:
std::cout默认仅输出6位有效数字,即使返回类型正确,也无法显示17位精度。
修改后的C++代码如下:
#include <chrono> #include <cstdint> #include <iostream> #include <iomanip> // 用于设置输出精度 uint64_t timeSinceEpochMillisec() { using namespace std::chrono; return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); } // 将返回类型改为double,保留浮点数精度 double JulianDateFromUnixTime(uint64_t t){ //Not valid for dates before Oct 15, 1582 return (static_cast<double>(t) / 86400000.0) + 2440587.5; } int main() { // 设置输出为17位有效数字,匹配JavaScript的精度 std::cout << std::setprecision(17) << JulianDateFromUnixTime(timeSinceEpochMillisec()) << std::endl; return 0; }
关键修改说明
- 返回类型调整:把
uint64_t改为double,双精度浮点数可精确表示儒略日期的整数部分(约2.4e6,远小于double能精确表示的整数上限2^53),同时保留足够的小数位精度。 - 强制浮点运算:将
t转换为double后再执行除法,避免整数除法直接截断小数的问题。 - 设置输出精度:通过
std::setprecision(17)让cout输出17位有效数字,确保完整显示计算结果的精度。
如果需要更高精度,可考虑替换为long double类型,但对于毫秒级输入的儒略日期,double已足够满足17位精度需求。
内容的提问来源于stack exchange,提问作者Thinker-101
相关产品推荐
相关产品推荐

