使用大数类型的例子(时间显示)

简介: 使用大数类型的例子(时间显示)

一、题目描述
小蓝要和朋友合作开发一个时间显示的网站。
在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从1970年1月1日00:00:00到当前时刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。

二、输入描述
输入一行包含一个整数,表示时间。

三、输出描述
输出时分秒表示的当前时间,格式形如HH;MM;SS,其中HH表示时,值为0到23,MM表示分,值为0到59,ss表示秒,值为0到59。时、分、秒不足两位时补前导0

四、解题思路
首先,分两种情况处理,第一种是输入的整数大于一天的总秒数,第二种是输入的整数小于一天的总秒数,如果大于的话,直接取余就可以得到当天从00.00.00开始的总秒数了,接下来接受需要对这个余数作时间处理了,把余数再除以3600(一个小时)得到的结果就是当天的小时数,余数即为剩下的分钟数和秒数了,然后再把得到的余数除以60得到的结果就是分钟数,余数就是秒数了。最后作前导0处理即可啦。

五、第一种算法?
import java.util.Scanner;

public class day03 {

public static void main(String[] args) {
    //一天的总秒数
    double day_second = 24*60*60;
    Scanner scanner = new Scanner(System.in);
    //输入一个整数
    while(scanner.hasNextDouble()) {
        double seconds = scanner.nextDouble();
        //如果输入的整数大于一天的总秒数
        if (seconds > day_second) {
            double yuShu = seconds % day_second;
            System.out.println(count(yuShu));
        }
        //如果输入的整数小于一天的总秒数
        else {
            System.out.println(count(seconds));
        }
    }
}
public static String count(double arg){
    String str_h = String.format("%.8f",arg/3600);
    int k1 = str_h.indexOf(".");
    String str_h_1 = str_h.substring(0,k1);
    double j_minutes = arg - Double.parseDouble(str_h_1)*3600;
    String str_m = String.format("%.8f",j_minutes/60);
    int k2 = str_m.indexOf(".");
    String str_m_1 = str_m.substring(0,k2);
    int second = (int) (j_minutes - Double.parseDouble(str_m_1)*60);
    if(str_h_1.equals("24")){
        str_h_1 = "00";
    }
    String str_s_1 = getString1(String.valueOf(second));
    str_h_1 = getString1(str_h_1);
    str_m_1 = getString1(str_m_1);
    return str_h_1+":"+str_m_1+":"+str_s_1;
}

private static String getString1(String str_m_1) {
    if(str_m_1.length()==1){
        str_m_1 += "0";
        StringBuilder buffer = new StringBuilder(str_m_1);
        StringBuilder buffer1 = buffer.reverse();
        str_m_1 = buffer1.toString();
    }
    return str_m_1;
}

}

count方法是得出最后结果的,getString1方法是给时分秒加上前导0的。

好了,现在让我们来看看运行结果:

44e8f81478bc4afdb53d6b0fc953f1f8.png

好了,你以为到这里就结束了吗,其实并没有,当我发现输入的数值过大时,就会产生问题了,例如:

7d36a096e6664ba3af0f6849dcece750.png

第一个输入很明显,个位数是9,然后得到的秒数的个位数应该也是9,但是结果却并没有,而且比他大一的数得出的时间还是和他的结果一样。So 为什么呢,其实这原因是因为定义的数据类型是double,双精度浮点数,当数值过大时,在计算机存储中一样会产生精度丢失,所以不能这样做。

于是我又想到了用java中有的超级方便的大数类型,刷题必备的。

就有了第二种算法

package day03;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Scanner;

public class completeDay03 {

public static void main(String[] args) {
    //一天的总秒数
    BigDecimal day_second = new BigDecimal("86400");
    BigDecimal seconds;
    //作为标志数
    BigDecimal flag;
    Scanner scanner = new Scanner(System.in);
    while(scanner.hasNextBigDecimal()) {
        //输入一个整数
        seconds = scanner.nextBigDecimal();
        //取得输入的整数与一天的总秒数取最大值
        flag = seconds.max(day_second);
        //如果输入的整数大于一天的总秒数
        if (flag.equals(seconds)) {
            //直接取余代入即可
            BigDecimal yuShu = seconds.remainder(day_second);
            System.out.println(count(yuShu));
        }
        //如果输入的整数小于一天的总秒数
        else {
            //直接代入方法即可
            System.out.println(count(seconds));
        }
    }
}
public static String count(BigDecimal arg){
    //首先获得一天的小时数是多少,中间参数0是保留多少位小数,RoundingMode.DOWN的意思是向零方向舍入
    String hours = String.format("%.0f",arg.divide(new BigDecimal("3600"),0, RoundingMode.DOWN));
    //上面取得了小时数之后,还得获得剩下的秒数
    BigDecimal j_minutes = arg.subtract( new BigDecimal(hours).multiply(new BigDecimal("3600")));
    //取得分钟数
    String minutes = String.format("%.0f",j_minutes.divide(new BigDecimal("60"),0, RoundingMode.DOWN));
    //取得秒数
    String second = String.format("%.0f",j_minutes.subtract( new BigDecimal(minutes).multiply(new BigDecimal("60"))));
    //下面为了符合题目要求,作输出字符串整理
    if(hours.equals("24"))
        hours = "00";
    hours = getString1(hours);
    second = getString1(second);
    minutes = getString1(minutes);
    return hours+":"+minutes+":"+second;
}

private static String getString1(String str_m_1) {
    if(str_m_1.length()==1){
        str_m_1 += "0";
        StringBuilder buffer = new StringBuilder(str_m_1);
        StringBuilder buffer1 = buffer.reverse();
        str_m_1 = buffer1.toString();
    }
    return str_m_1;
}

}
好了,看一下运行结果:
7e92f50476f44d8ea7c7b6d74e98ba74.png
4b6dc801152f479a842e2b67dace083a.png

ok ,没发现出有问题了,果然大数类型yyds,今晚在整理出关于大数类型的一些常用方法和配套使用的一些常量。

相关文章
|
2月前
|
存储 Unix C++
c++时间形式转换
【10月更文挑战第29天】在 C++ 中,时间形式转换主要涉及将时间在不同表示形式之间转换,如字符串与 `tm` 结构或 `time_t` 类型之间的转换。常用的基本时间类型包括 `time_t` 和 `tm` 结构,转换函数有 `strftime` 和 `strptime`,可以满足大多数时间处理需求。此外,还可以通过自定义类来扩展时间转换功能。
|
6月前
|
C#
C# 版本的 计时器类 精确到微秒 秒后保留一位小数 支持年月日时分秒带单位的输出
这篇2010年的文章是从别处搬运过来的,主要包含一个C#类`TimeCount`,该类有多个方法用于处理时间相关的计算。例如,`GetMaxYearCount`计算以毫秒为单位的最大年数,`GetCurrentTimeByMiliSec`将当前时间转换为毫秒,还有`SecondsToYYMMDDhhmmss`将秒数转换为年月日时分秒的字符串。此外,类中还包括一些辅助方法,如处理小数点后保留一位数字的`RemainOneFigureAfterDot`。
|
7月前
|
C++
【代码片段】【C++】获取当前时间戳并生成固定格式字符串
【代码片段】【C++】获取当前时间戳并生成固定格式字符串
74 0
|
7月前
将毫秒数量转换为时分秒字符串(毫秒数→转换为→00:00:00.000或00天00时00分00秒000毫秒形式)
将毫秒数量转换为时分秒字符串(毫秒数→转换为→00:00:00.000或00天00时00分00秒000毫秒形式)
|
JavaScript 前端开发
javascript以当前日期为准计算昨天、7天、30天直接输出日期的解决方案
javascript以当前日期为准计算昨天、7天、30天直接输出日期的解决方案
79 0
|
JSON JavaScript 前端开发
javascript对象数据合并实现补齐24小时时间段同时赋值0的解决方案
javascript对象数据合并实现补齐24小时时间段同时赋值0的解决方案
129 0
|
算法
改错题:用户从键盘任意输入一个数字表示月份值n,程序显示该月份对应的英文表示,若n不在1~12之间,则输出“Illegal month”。 注意: (1)请将修改正确后的完整源程序拷贝粘贴到答题区内。
改错题:用户从键盘任意输入一个数字表示月份值n,程序显示该月份对应的英文表示,若n不在1~12之间,则输出“Illegal month”。 注意: (1)请将修改正确后的完整源程序拷贝粘贴到答题区内。
335 0
|
存储 SQL 前端开发
解决方案:记录一下Date类型在传值时遇见的若干坑(String类型转为Date类型、mysql的表设置、UTC的设置)
解决方案:记录一下Date类型在传值时遇见的若干坑(String类型转为Date类型、mysql的表设置、UTC的设置)
解决方案:记录一下Date类型在传值时遇见的若干坑(String类型转为Date类型、mysql的表设置、UTC的设置)