上次发贴,由于时间关系,把贴结了,问题还没解决,另外不想用字符串的问题解决,所以继续求教,问题解决,马上结贴:
max,min两个数
1.max要求向上取整,min 要求向下取整,
2.max,min要求是以0.5,5,00,,结尾
如:max =123 向上取整 125
min =17 向下取整 15
如果是小数 max =0.7 取整1.0,
min =0.2向下取整0.0
另外算法对精度的要求很高,误差要求在1/1000。以所求教下大家,看看大家有没有好一点的建议。
我个人通过取模的形式来实现的,误差太多,行不通!

解决方案 »

  1.   

    对了max = 12.3想上取===多少?12.5?or15?
      

  2.   

    max = 12.3想上取===多少?12.5?or15?
    对于这个,我本来想取15,可是这样以来我的精度就拉大了,所以我想了一下,还是12.5,
      

  3.   

    又仔细看了一遍你的题意描述,发现完全不知所云,也没给相应的sample数据进行说明,函数的表达也不够规范好像
    -->max,min要求是以0.5,5,00,,结尾,最后两个逗号之间省略的是指什么?
    -->max =0.7 取整1.0 ,是指max(0.7)=1.0?那max(0.07)? max(0.007)?
      

  4.   

    to :wizardblue() 
    呵呵,我没有说清楚,max,min两个数,我并没有说函数,-->max,min要求是以0.5,5,00..(是省略号,意思就是对应的0.05,0.005...),结尾-->max =0.7 取整1.0 ,是指max(0.7)=1.0?那max(0.07)? = 0.1 max(0.007)?0.01
      

  5.   

    BigDecimal 类应该可以解决你的需求。
    好好研究下吧。
      

  6.   

    C#与之对应的应该是Decimal 先看看去,希望那位兄弟有好的算法不要吝啬啊,分不够在加
      

  7.   

    呵呵,可异C#中没有RoundingMode这样的enum,不做API的指望了!
      

  8.   

    想了一晚上,看到你们写的类(RoundingMode)我没有见过
    自己用字符串的形式写了一个获得max的不知道行不行
    public double getMax(double maxa)
    {   
    int pointPos = 0;//小数点的位置
    int declen = 0; //小数的长度
    double result = 0.0;//结果
    String strmax = String.valueOf(maxa);//转成字符串
    String strmaxafter="";//计算结果后的字符串值
                      //小数
    if(strmax.indexOf(".")>0)
    {
    pointPos = strmax.indexOf(".");
    declen = strmax.length() - pointPos;
    //整数部分和小数部分的获取
    String intpart = strmax.substring(0,pointPos);
    String doublepart = strmax.substring(pointPos + 1,strmax.length());
    //去掉小数点,如0.204==〉0204
    String num=intpart + doublepart;
                                //变成整数
    int z = Integer.parseInt(num);
    //204==〉205
    if(z % 5 != 0)
    {
    z = (z/5 + 1) * 5;
    }
                               //205==〉“205”
    strmaxafter = String.valueOf(z);
                                //左边补零
    while(strmaxafter.length() < strmax.length() - 1)
    {
    strmaxafter = "0" + strmaxafter;
    }
                                //整数部分取得
    intpart = strmaxafter.substring(0,strmax.length() - declen);                    //小数部分取得
    doublepart = strmaxafter.substring(strmax.length() - declen,strmaxafter.length());
    result = Double.parseDouble(intpart + "." + doublepart);
    return result;
    }
      

  9.   

    楼主的整数和小数范围?假如非得用bigInt搞得定的话,实际也是按数组拆分的
      

  10.   

    呵呵,谢谢你For_suzhen,我也在期待!
      

  11.   

    个人认为,用字符串处理是最好的,否则难以保证精度
    不用字符串的话,可以试一下如下的代码(精度上可能存在问题)
            double x=3.3333333;
            double tmp=x;
            int i=1;
            // 小数位转成整数
            while(tmp!=Math.floor(tmp)){
                i=i*10;
                // 如果使用tmp=tmp*10的方式则会出现精度问题
                tmp=x*i;
            }
            int div=((int)tmp)/10;
            // 取最后一位数字
            int mod=((int)tmp)%10;
            double max=div*10;
            double min=div*10;
            if(mod<5){
                // x=0.3
                // max=0.5
                // min=0.0
                max+=5;
            }else if(mod==5){
                // x=0.5
                // max=0.5
                // min=0.5
                max+=5;
                min=max;
            }else{
                // x=0.7
                // max=1.0
                // min=0.5
                max+=10;
                min+=5;
            }
            max=max/i;
            min=min/i;
            System.out.println("max = "+max);
            System.out.println("min = "+min);
      

  12.   

    private static void testNum(){
    String max = "234.4";
    String min = "123.1";
    double powerN = 1;

    if(max.indexOf(".") != -1){
    int len = max.length() - max.indexOf(".") - 1;
    powerN = Math.pow(10,len);
    }
    String rtnMax = "" + getRtn(Double.parseDouble(max) * powerN, true) / powerN;
    max = max.indexOf(".") != -1 ? rtnMax : rtnMax.substring(0,rtnMax.indexOf("."));

    powerN = 1;
    if(min.indexOf(".") != -1){
    int len = min.length() - min.indexOf(".") - 1;
    powerN = Math.pow(10,len);
    }
    String rtnMin = "" + getRtn(Double.parseDouble(min) * powerN, false) / powerN;
    min = min.indexOf(".") != -1 ? rtnMin : rtnMin.substring(0,rtnMin.indexOf("."));

    System.out.println(max + " : " + min);
    }

    private static double getRtn(double number,boolean flgUpDown){

    if(number%5 == 0) return number;
    if(flgUpDown) number = number + 5 - number%5;
    if(!flgUpDown) number = number - number%5;

    return number;
    }
      

  13.   

    To:shan1119(大天使)
    谢谢看见了,不过我的想能不能不用字符串的方法来解决而已。
    可能是我说的不太清楚吧,不过不是谢谢大家!
    实际上我是想实现一个轴线的算法(C#GDI+),Max是Y轴的最大值,min是Y轴的最小值,而(max-min)/轴线数量 就是Y轴每个刻度的刻度值,所以无论在何什么情况下,轴线的刻度都可以自动适应,比如最小值是5,最大值是50,其刻度值是(5.0,9.5,13.5,,,,),而我希望中间的步长是一个5 ,或者0.5之类的值,当然小数可以适当调整,类似(0.1,0.001),而这中间还有考虑一个精度的问题,不知道那位兄弟有没有做过,希望能给一些参考,在给50分,继续等!
      

  14.   

    package net.hjc.test;/**
     * @author 棉花糖
     * @version 1.0, 2007/02/10
     */
    public class Format
    {
    public static int min (int $n)
    {
    return Format.cArrToInt(Format.intToFC($n, true));
    }

    public static double min (double $n)
    {
    return Format.cArrToDouble(Format.doubleToFC($n, true));
    } public static int max (int $n)
    {
    char[] t = Format.intToFC($n, false);
    return Format.cArrToInt(t) + ((t[t.length-1] == '0') ? 10 : 0);
    }

    public static double max (double $n)
    {
    int nInt = (int)$n;
    if ($n > nInt + 0.5) return ++nInt;

    char[] t = Format.doubleToFC($n, false);
    int    l = t.length;

    int i = 0;
    while (t[i++] != '.');

    return Format.cArrToDouble(t) + ((t[l-1] == '0') ? Math.pow(.1, l-i-1) : 0);
    }

    private static char[] intToFC (int $n, boolean $b)
    {
    char[] t = Integer.toString($n).toCharArray();
    Format.tmp(t, t.length, $b);
    return t;
    }

    private static char[] doubleToFC (double $n, boolean $b)
    {
    char[] t = Double.toString($n).toCharArray();
    Format.tmp(t, t.length, $b);
    return t;
    }

    private static int cArrToInt (char[] $c)
    {
    return Integer.parseInt((String.valueOf($c)));
    }

    private static double cArrToDouble (char[] $c)
    {
    return Double.parseDouble((String.valueOf($c)));
    }

    private static void tmp (char[] $t, int l, boolean $b)
    {
    if ($t[l-1] < '5') $t[l-1] = ($b) ? '0' : '5';
    else if ($t[l-1] > '5') $t[l-1] = ($b) ? '5' : '0';
    }
    }〓〓〓〓〓〓〓〓〓〓
    以下是单元测试代码
    〓〓〓〓〓〓〓〓〓〓package net.hjc.test;import static org.junit.Assert.*;
    import org.junit.Test;public class FormatTest
    {
    @Test
    public void testMinInt()
    {
    assertEquals(Format.min(13), 10);
    assertEquals(Format.min(15), 15);
    assertEquals(Format.min(17), 15);
    } @Test
    public void testMinDouble()
    {
    assertEquals(Format.min(12.3), 12.0);
    assertEquals(Format.min(12.5), 12.5);
    assertEquals(Format.min(12.7), 12.5);

    assertEquals(Format.min(12.13), 12.10);
    assertEquals(Format.min(12.15), 12.15);
    assertEquals(Format.min(12.17), 12.15);
    } @Test
    public void testMaxInt()
    {
    assertEquals(Format.max(13), 15);
    assertEquals(Format.max(15), 15);
    assertEquals(Format.max(17), 20);
    } @Test
    public void testMaxDouble()
    {
    assertEquals(Format.max(12.3), 12.5);
    assertEquals(Format.max(12.5), 12.5);
    assertEquals(Format.max(12.7), 13.0);

    assertEquals(Format.max(12.13), 12.15);
    assertEquals(Format.max(12.15), 12.15);
    assertEquals(Format.max(12.17), 12.2);
    }
    }
      

  15.   

    可能我理解的不对,觉得很简单啊, 我做的一个算法,大家看看
    这样理解对不对?package AlgorithmTry;
    /*
     * 先分别做一个把一位小数向上取整和向下取整的函数, 
     * 然后把需要取整的数乘一个10的N次方调整到一位小数,
     * 取整完在调回去
     */
    public class Truncer {
       
    public static int presicy=10000; //精度
    public static double upTrunc(double src) //向上取整
    {
    if(!Truncer.scalable(src))
    {
      return src;
    }
       long l=Double.valueOf(src).longValue();
       double ret;
       double db=src-l;
       if(db>0.5)
       {
       ret = l+1.0;
       }
       else if(db<0.5)
       {
       ret = l+0.5;
       }
       else
       {
       ret = src;
       }
       return ret;
    }
    public static double downTrunc(double src) //向下取整
    {
    if(!Truncer.scalable(src))
    {
      return src;
    }
       long l=Double.valueOf(src).longValue();
       double ret;
       double db=src-l;
       if(db>0.5)
       {
       ret = l+0.5;
       }
       else if(db<0.5)
       {
       ret = l;
       }
       else
       {
       ret = src;
       }
       return ret;
    }

    //判断输入的数精度是否比要求的低,低的则不需要取整
    public static boolean scalable(double src)
    {
    boolean bret=true;
      int totalcnt=1;
      
      while(Truncer.presicy/10*totalcnt>0)
      {
      totalcnt++;
      }
      for(int i=1; i<=totalcnt;i++)
      {
      if(Double.valueOf(src*10*i).intValue()/(i*10.0)==src)
      {
      bret=false;
      break;
      }
      }
      return bret;
    }
    public static void main(String args[])
    {

    double sampledb=15725.0114124;
    int scale=Truncer.presicy;
    System.out.println(Truncer.upTrunc(sampledb*scale)/scale);
        System.out.println(Truncer.downTrunc(sampledb*scale)/scale);
    }
    }
      

  16.   

    package net.hjc.test;/**
     * @author 棉花糖
     * @version 1.0, 2007/02/10
     */
    public class Format
    {
    public static int min (int $n)
    {
    return Format.cArrToInt(Format.intToFC($n, true));
    }public static double min (double $n)
    {
    return Format.cArrToDouble(Format.doubleToFC($n, true));
    }public static int max (int $n)
    {
    char[] t = Format.intToFC($n, false);
    return Format.cArrToInt(t) + ((t[t.length-1] == '0') ? 10 : 0);
    }public static double max (double $n)
    {
    int nInt = (int)$n;
    if ($n > nInt + 0.5) return ++nInt;char[] t = Format.doubleToFC($n, false);
    int    l = t.length;int i = 0;
    while (t[i++] != '.');return Format.cArrToDouble(t) + ((t[l-1] == '0') ? Math.pow(.1, l-i-1) : 0);
    }private static char[] intToFC (int $n, boolean $b)
    {
    char[] t = Integer.toString($n).toCharArray();
    Format.tmp(t, t.length, $b);
    return t;
    }private static char[] doubleToFC (double $n, boolean $b)
    {
    char[] t = Double.toString($n).toCharArray();
    Format.tmp(t, t.length, $b);
    return t;
    }private static int cArrToInt (char[] $c)
    {
    return Integer.parseInt((String.valueOf($c)));
    }private static double cArrToDouble (char[] $c)
    {
    return Double.parseDouble((String.valueOf($c)));
    }private static void tmp (char[] $t, int l, boolean $b)
    {
    if ($t[l-1] < '5') $t[l-1] = ($b) ? '0' : '5';
    else if ($t[l-1] > '5') $t[l-1] = ($b) ? '5' : '0';
    }
    }
      

  17.   

    〓〓〓〓〓〓〓〓〓〓〓〓〓〓
      以下是楼上的单元测试代码
    〓〓〓〓〓〓〓〓〓〓〓〓〓〓package net.hjc.test;import static org.junit.Assert.*;
    import org.junit.Test;public class FormatTest
    {
    @Test
    public void testMinInt()
    {
    assertEquals(Format.min(13), 10);
    assertEquals(Format.min(15), 15);
    assertEquals(Format.min(17), 15);
    }@Test
    public void testMinDouble()
    {
    assertEquals(Format.min(12.3), 12.0);
    assertEquals(Format.min(12.5), 12.5);
    assertEquals(Format.min(12.7), 12.5);assertEquals(Format.min(12.13), 12.10);
    assertEquals(Format.min(12.15), 12.15);
    assertEquals(Format.min(12.17), 12.15);
    }@Test
    public void testMaxInt()
    {
    assertEquals(Format.max(13), 15);
    assertEquals(Format.max(15), 15);
    assertEquals(Format.max(17), 20);
    }@Test
    public void testMaxDouble()
    {
    assertEquals(Format.max(12.3), 12.5);
    assertEquals(Format.max(12.5), 12.5);
    assertEquals(Format.max(12.7), 13.0);assertEquals(Format.max(12.13), 12.15);
    assertEquals(Format.max(12.15), 12.15);
    assertEquals(Format.max(12.17), 12.2);
    }
    }
      

  18.   

    多谢楼上的兄弟,不说了,明天结贴,在把我的程序话到blog,用自己的方式解决的,自己认为自己写的堪称垃圾,大伙的我行不通!
      

  19.   

    不行?那么请给出你的测试数据
    我倒要看看哪里不行别告诉我没有 main 函数你就不会用了……
      

  20.   

    呵呵,楼上的main函数是什么东西啊!我都不知道啊!