精华内容
下载资源
问答
  • Java中可以通过System.currentTimeMillis()或者System.nanoTime() (JDK>=5.0) 方法获得当前的时间的精确值。但是通过阅读Javadoc,我们发现这两个方法并不一定保证得到你所期望的精度。先来看System....

    在Java中可以通过System.currentTimeMillis()或者System.nanoTime() (JDK>=5.0) 方法获得当前的时间的精确值。但是通过阅读Javadoc,我们发现这两个方法并不一定保证得到你所期望的精度。先来看System.currentTimeMillis():

    Returns the current time in milliseconds. Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger. For example, many operating systems measure time in units of tens of milliseconds.

    诚如上面所说返回值的粒度依赖于底层操作系统,那么它在不同的平台上到底能提供是么样的精度,是否像函数名所写的那样真正精确到1毫秒呢?看下面一段测试程序:

    public class ClockAccuracyTest {

    public static void main(String args[]) {

    SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss:SSS");

    int size = 4000000;

    // create an array to hold millisecond times

    // and loop to capture them

    long times[] = new long[size];

    for (int i = 0; i < size; i++) {

    times[i] = System.currentTimeMillis();

    }

    // now display the unique times

    long time = times[0];

    long previousTime = times[0];

    long count = 0;

    Set deltas = new HashSet();

    long delta = 0;

    long minDelta = Long.MAX_VALUE;

    long maxDelta = Long.MIN_VALUE;

    for (int i = 0; i < size; i++) {

    if (times[i] > time) {

    delta = time - previousTime;

    deltas.add(delta);

    if (delta > 0 && delta < minDelta) {

    minDelta = delta;

    } else if (delta > maxDelta) {

    maxDelta = delta;

    }

    System.out.print("raw=");

    System.out.print(time);

    System.out.print(" | formatted=");

    System.out.print(formatter.format(new Date(time)));

    System.out.print(" | frequency=");

    System.out.print(count);

    System.out.print(" | delta=");

    System.out.print(delta);

    System.out.println("ms");

    previousTime = time;

    time = times[i];

    count = 0;

    } else {

    count++;

    }

    }

    System.out.println("");

    System.out.println("Minimum delta : " + minDelta + "ms");

    System.out.println("Maximum delta : " + maxDelta + "ms");

    }

    }

    这段程序循环调用System.currentTimeMillis()方法,记录并显示结果,在我机器(Windows XP SP3)上运行输出如下:

    raw=1255659457187 | formatted=16-十月-2009 10:17:37:187 | frequency=147250 | delta=0ms

    raw=1255659457203 | formatted=16-十月-2009 10:17:37:203 | frequency=447674 | delta=16ms

    raw=1255659457218 | formatted=16-十月-2009 10:17:37:218 | frequency=436583 | delta=15ms

    raw=1255659457234 | formatted=16-十月-2009 10:17:37:234 | frequency=439379 | delta=16ms

    raw=1255659457250 | formatted=16-十月-2009 10:17:37:250 | frequency=426547 | delta=16ms

    raw=1255659457265 | formatted=16-十月-2009 10:17:37:265 | frequency=447048 | delta=15ms

    raw=1255659457281 | formatted=16-十月-2009 10:17:37:281 | frequency=459522 | delta=16ms

    raw=1255659457296 | formatted=16-十月-2009 10:17:37:296 | frequency=414816 | delta=15ms

    raw=1255659457312 | formatted=16-十月-2009 10:17:37:312 | frequency=458826 | delta=16ms

    Minimum delta : 15ms

    Maximum delta : 16ms

    输出的四列从左到右分别是原始的毫秒值、格式化的时间、每个值循环的次数、与上一个不同值的差。可以看到在Windows上 System.currentTimeMillis()方法并不能提供1ms的计时粒度,它的粒度为15~16ms,从网上的其它文章来看,这个结果基本上是一致的,这也验证了Javadoc上所写的“the granularity of the value depends on the underlying operating system and may be larger ”。在其他操作系统,如Linux、Solaris上,我没有进行测试,但从网上的一些测试结果看,currentTimeMillis方法在某些操作系统能够提供精确的1毫秒计时粒度。这是不是意味着Java在Windows上无法进行精确的毫秒计时了呢?当然不是,一种解决方案是采用JNI调用,利用Windows系统提供的函数计时;还有一个更简便的办法,就是使用JDK5.0加入的System.nanoTime()方法。Javadoc对该方法的描述如下:

    Returns the current value of the most precise available system timer, in nanoseconds.

    This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.

    它返回系统能够提供的最为精确的计时,以纳秒(10亿分之一秒)为单位,但并不保证纳秒级精度。把上面的测试程序中黑体的一行改为“times[i] = System.nanoTime();”,并把所有的“ms”该成“ns”,循环次数改为10。运行输出如下:

    raw=8705892679376 | formatted=17-十一月-2245 23:31:19:376 | frequency=1 | delta=0ns

    raw=8705892681053 | formatted=17-十一月-2245 23:31:21:053 | frequency=0 | delta=1677ns

    raw=8705892682449 | formatted=17-十一月-2245 23:31:22:449 | frequency=0 | delta=1396ns

    raw=8705892683846 | formatted=17-十一月-2245 23:31:23:846 | frequency=0 | delta=1397ns

    raw=8705892685522 | formatted=17-十一月-2245 23:31:25:522 | frequency=0 | delta=1676ns

    raw=8705892686919 | formatted=17-十一月-2245 23:31:26:919 | frequency=0 | delta=1397ns

    raw=8705892688316 | formatted=17-十一月-2245 23:31:28:316 | frequency=0 | delta=1397ns

    raw=8705892689713 | formatted=17-十一月-2245 23:31:29:713 | frequency=0 | delta=1397ns

    raw=8705892691110 | formatted=17-十一月-2245 23:31:31:110 | frequency=0 | delta=1397ns

    Minimum delta : 1396ns

    Maximum delta : 1676ns

    我们看到frequency=0,这意味着每执行一次循环,nanoTime方法的返回值都发生了改变,改变的差值平均大约为1467ns(不同性能的机器结果会不同)。这说明nanoTime方法计时的精度是非常高的,粒度比方法本身的调用执行耗时还要小。

    回到上面的问题,如何在windows上实现精确的毫秒计时呢。答案就是用“System.nanoTime()/1000000L”代替“System.currentTimeInMills()”。把测试程序黑体的一行代码改为"times[i] = System.nanoTime()/1000000L;",循环次数5000,运行输出结果如下:

    raw=9487129 | formatted=01-一月-1970 10:38:07:129 | frequency=202 | delta=0ms

    raw=9487130 | formatted=01-一月-1970 10:38:07:130 | frequency=704 | delta=1ms

    raw=9487131 | formatted=01-一月-1970 10:38:07:131 | frequency=621 | delta=1ms

    raw=9487132 | formatted=01-一月-1970 10:38:07:132 | frequency=618 | delta=1ms

    raw=9487133 | formatted=01-一月-1970 10:38:07:133 | frequency=696 | delta=1ms

    raw=9487134 | formatted=01-一月-1970 10:38:07:134 | frequency=695 | delta=1ms

    raw=9487135 | formatted=01-一月-1970 10:38:07:135 | frequency=698 | delta=1ms

    raw=9487136 | formatted=01-一月-1970 10:38:07:136 | frequency=698 | delta=1ms

    Minimum delta : 1ms

    Maximum delta : 1ms

    我们看到粒度delta变为了1ms。循环次数frequency平均为676,也就是说每个循环运运行耗时1/676=0.001479ms=1479ns,与上一个测试结果的1467ns吻合。

    结论:如果你的Java程序需要高精度的计时,如1毫秒或者更小,使用System.nanoTime()方法,它完全可以满足你的需求。如果不行的话,建议你换台更快的机器试试:)

    展开全文
  • 要获得临时查询的精度,请使用TemporalQuery接口和TemporalQueries的precision()方法-TemporalQueryprecision=TemporalQueries.precision();GettheprecisionforLocalDate:LocalDate.now().query(precision)...

    要获得临时查询的精度,请使用TemporalQuery接口和TemporalQueries的precision()方法-TemporalQueryprecision = TemporalQueries.precision();

    Get the precision for LocalDate:

    LocalDate.now().query(precision)

    Get the precision for LocalTime:

    LocalTime.now().query(precision)

    Get the precision for YearMonth:

    YearMonth.now().query(precision)

    Get the precision for Year:

    Year.now().query(precision)

    示例import java.time.LocalDate;

    import java.time.LocalDateTime;

    import java.time.LocalTime;

    import java.time.Year;

    import java.time.YearMonth;

    import java.time.temporal.TemporalQueries;

    import java.time.temporal.TemporalQuery;

    import java.time.temporal.TemporalUnit;

    public class Demo {

    public static void main(String[] args) {

    TemporalQueryprecision = TemporalQueries.precision();

    System.out.println("TemporalQueries precision...");

    System.out.println(LocalDate.now().query(precision));

    System.out.println(LocalTime.now().query(precision));

    System.out.println(LocalDateTime.now().query(precision));

    System.out.println(YearMonth.now().query(precision));

    System.out.println(Year.now().query(precision));

    }

    }

    输出结果TemporalQueries precision...

    Days

    Nanos

    Nanos

    Months

    Years

    展开全文
  • 我在互联网上看到我应该使用System.nanoTime(),但这对我来说不起作用 – 它给了我毫秒级精度时间。我只需要在我的函数执行之前和之后的微秒,以便我知道需要多长时间。我使用的是Windows XP。基本上,我有这样的...

    我在互联网上看到我应该使用System.nanoTime(),但这对我来说不起作用 – 它给了我毫秒级精度的时间。我只需要在我的函数执行之前和之后的微秒,以便我知道需要多长时间。我使用的是Windows XP。

    基本上,我有这样的代码,例如,在一个java链接列表中,可以执行1百万次到10万次的插入。问题是我无法测量精确度;有时将所有内容插入较小的列表中需要较少的时间。

    以下是一个例子:

    class test

    {

    public static void main(String args[])

    {

    for(int k=1000000; k<=10000000; k+=1000000)

    {

    System.out.println(k);

    LinkedList aux = new LinkedList();

    //need something here to see the start time

    for(int i=0; i

    aux.addFirst(10000);

    //need something here to see the end time

    //print here the difference between both times

    }

    }

    }

    我做了很多次 – 有一个外部循环为每个k做20次,但结果不好。有时候,花费更少的时间来进行1000万次插入超过100万次,因为我没有得到正确的测量时间与我现在使用的(System.nanoTime())

    编辑2:是的,我正在使用Sun JVM。

    编辑3:我可能在代码中做错了,我会看到如果改变它做我想要的。

    编辑4:我的错误,似乎System.nanoTime()工作。唷。

    展开全文
  • 0.05+0.01=0.060000000000000005才发现Java的double原来精度那么蛋疼. 网上推荐BigDecimal代替double, 果然不错, 那就用BigDecimal替换. 等所有的double都换之后, 狗血的事情发生了, BigDecimal是如此的慢, 以至于...

    0.05+0.01=0.060000000000000005

    才发现Java的double原来精度那么蛋疼. 网上推荐BigDecimal代替double, 果然不错, 那就用BigDecimal替换. 等所有的double都换之后, 狗血的事情发生了, BigDecimal是如此的慢, 以至于跑一个用例花了之前N倍的时间, 怎么办, 只能用一个折中的办法, 数值表示仍然用double, 数值计算用BigDecimal。

    既然Java的double问题那么多, 我当前系统用double表示数值, 会不会出现偏差? 如果Java中采用BigDecimal效率这么低, 那些大型交易所, 性能要求极高, 如何控制延迟呢? 或者还有其他更好的技术??

    double奇葩的精度. 试一下C语言的,结果如下:

    printf("%lf", 0.01 + 0.05);  #输出结果为0.060000.

    怎么会这样呢??是精度, 保留的精度不对, 于是设定保留小数点后18位, 因为java的输出小数点后有18位:

    printf("%.18lf", 0.01 + 0.05);  #输出结果为0.060000000000000005.

    试了下python也是如此, 毕竟编程语言基本采用IEEE754标准, 存储方式相同, 计算也都由CPU完成, 跟语言无关, 而是跟IEEE754标准有关?接着看下Java语言:

    System.out.println(0.09 + 0.01);  #输出结果为0.09999999999999999.

    但是, 如果取小数点后10位以内, 结果还是好的, 而且一般现实也不需要那么高的精度, 但是, 倘若每次计算都做一次round, 势必性能大打折扣!然而不做round, 的确是不严谨的作法, 如果是支付场景, 0.09+0.01<0.1, 那么这次交易就完成不了, 这是绝对不能容忍的错误!

    谈了现象, 再谈谈原因, 其实很简单, 10进制的世界, 对于0, 1的世界的计算机来说, 呵呵~~

    尾数整数能表示最大值是2^54−1, 即当你的整数部分大于或接近2^54−1时, 如果有小数, 则小数精度丢失非常严重.:在整数部分不太大的情况下, double可以保证精度丢失微乎其微;而当整数部分过大时, 小数部分会做非常粗暴省略.

    double之所以会产生精度的丢失, 最根本的因素是用于表示小数的二进制位数不够, 然后做round, 造成丢失.使用double, 保留小数最多不超过3位, 勉勉强强应付几百个亿, 那对于金融, 科学计算领域, 可以想见, double已经不能满足需求了!因此, 采用Java BigDecimail是非常有必要的.

    申明:这里提到的double都是采用IEEE754规范的64位浮点数.

    展开全文
  • Java中的时间精度

    千次阅读 2017-05-01 00:54:12
    先引用别人之前的实验结论 ...循环次数frequency平均为676,也就是说每个循环运运行耗时1/676=0.001479ms=1479ns,与上一个测试结果的1467ns吻合。...结论:如果你的Java程序需要高精度的计时,如1
  • Java中的时间精度

    万次阅读 2009-10-15 21:37:00
    Java中可以通过System.currentTimeMillis()或者System.nanoTime() (JDK>=5.0) 方法获得当前的时间的精确值。但是通过阅读Javadoc,我们发现这两个方法并不一定保证得到你所期望的精度。先来看System....
  • java最高精度时间差System.nanoTime()测试String,StringBuffer,StringBuilder拼接字符串的效率问题 在测试String,StringBuffer,StringBuilder之间的效率时,如果用System.currentTimeMillis()的前后时间差来比较...
  • 题目描述blablabla样例blablabla算法1blablabla时间复杂度分析:blablablaJava 代码import java.util.ArrayList;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java...
  • java已经有段时间了,可是遇到什么范围啊,精度啊就迷糊,虽然自己经常使用,自己的数据也从未超过int型的范围,但还是多了解下,用着才放心嘛……1. 范围float和double的范围是由指数的位数来决定的。float的指数...
  • java精度hdu4043

    2013-07-19 15:17:00
    数据量很大,最后又要进行gcd操作,java里竟然自带了一个gcd的函数,为了避免求大数取余和大数除法操作,还是用java比较快,而且这题对时间复杂度要求不是很高。 /* * To change this template, choose Tools |...
  • 一、问题产生 在C#和C++中有这样一个函数:void... 据说经过测试发现运行10万条数据进行测试发现nanoseconds精度只能达到1.03ms左右(注意依旧达不到微妙级、纳秒级) 但是比使用timeBeginPeriod精度要高。我没有测试这个
  • 实际使用中,经常需要使用不同精确度的Date,...Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、使用Of方法和使用With方法,性能对比,使用Of方法性能最优。1.减少时间精确度的三种方...
  • 我在Internet上看到应该...基本上,我有这段代码,例如,在Java链表中进行了1百万个到1000万个插入。问题是我无法正确测量精度;有时,花费较少的时间将所有内容插入较小的列表中。这是一个例子:class test{public ...
  • 因此,此采集过程应该是实时的,且具有微秒级的时间精度.我正在尝试用Java编程.到目前为止,已经能够从并行端口获取数据,但是很难保持时间间隔.我的问题是:是否真的有可能在Windows XP环境下以这种时间(以...
  • 一个J2SE或者J2ME日历应用程序需要根据用户的约定计划闹铃时间[1]。Sun提供的JavaAPI中类Timer和TimerTask被用来完成这些任务的实现和调度。java.util.Time和java.util.TimerTask统称为Java定时器框架,它们使程序员...
  • 前段时间, 因为要测试一个刚出炉的高频策略, 放实盘去跑吧, 怕出岔, 所以写了个简单的回测系统, 跑一遍历史数据. 其中有一部分是关于撮合系统, 简陋了点, 还算能跑得起来, 几个用例下来, 也没什么问题, 接着增加历史...
  • ChapterI.  Java的优缺点各种书上都有,这里只说说用Java做ACM-ICPC的特点: (1)最明显的好处是,...当然,这里只是指一般编程,想熟悉所有的Java库还是需要些时间的。事实上,Java只相当于C++的一个改进版,所...
  • JAVA溢出和精度损失

    2019-04-08 09:01:43
    java中使用强制转换有可能导致溢出或损失精度。 当把容量大的类型转换为容量小的类型时就有可能导致溢出; 比如吧int类型的2019转换成byte类型。Int类型的2019的源码、反码、和补码都是: 00000000 00000000 ...
  • 点击上方“布衣码农”,免费订阅~选择“设为星标”,第一时间免费获得更新~「布衣码农」万事万物皆可抽象,精度也都可以是一种对象~java.math包提供了java中的数学类,包括基本的浮点库、复杂运算以及任意精度的数据...
  • JAVA问题总结之30--输出当前精度为毫秒的时间并且按时间批量建立文件 1.TimeByMs.java package java1; import java.util.Date; import java.text.*; public class TimeByMs { public static void main(String...
  • 文章参考一位博友,由于时间太久忘了链接,见谅! 1 public class BigDecimalUtils { 2 3 private static final int DIV_SCALE = 10;// 除法精度(除不尽时保留10为小数) 4 5 /** 小数精确加法 */ ...
  • java.time类可以保存以纳秒为单位的值,但只能以毫秒为单位确定当前时间.这种限制是由于Clock的实现.在Java 9及更高版本中,新的Clock实现可以以更精细的分辨率获取当前时刻,具体取决于主机硬件和操作系统的限制,根据...
  • //会报异常 java.lang.IllegalStateException: Task already scheduled or cancelled task.setUserScheduleTimes(value); timerTaskMap.put(key, task);if (value !=null) { Date HHmmDate=value.getFirstTime(); ...
  • 根据SimpleDateFormat类文档,Java在其日期模式中不支持毫秒以上的时间粒度。因此,日期字符串2015-05-09 00:10:23.999750900 //最后9位数字表示纳秒通过模式解析时yyyy-MM-dd HH:mm:ss.SSSSSSSSS // 9个'S'符号...
  • 我在Fortran中编写了一个代码,用于读取具有4维数据[时间,级别,经度,纬度]的NetCDF文件 . 但是,我的代码会产生错误NetCDF: Start+count exceeds dimension bound在我正在使用的任何4-bit NetCDF文件上 . 例如,...
  • 给定m,n (1≤m≤50,0≤n≤1010000)m, n~(1 \le m \le 50, 0 \le n \le 10^{10000}) 求... 因为只要求整数部分,所以不必用 BigDecimal 类去二分,那样反而会浪费时间,最后判断边界值即可. 构造至 : lm, r=2ll^m ^m, ~
  • 作者为了更精确的定时,做了一点小小的改进,把执行RDTSC指令的时间,通过连续两次调用GetCycleCount函数计算出来并保存了起来,以后每次计时结束后,都从实际得到的计数中减掉这一小段时间,以得到更准确的计时数字...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 790
精华内容 316
关键字:

java时间精度

java 订阅