Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中解析工程符号_Java_Parsing - Fatal编程技术网

如何在Java中解析工程符号

如何在Java中解析工程符号,java,parsing,Java,Parsing,是否有一种简单的方法可以使用纯Java或Apache commons库将工程符号(1.2K、120m等)中的数字解析为双倍值。我正在编写一个使用找到的代码的代码。我计划实施我自己的解决方案。目标是重用Java框架中包含的现有解决方案。最好的方法是什么 编写自己的解决方案时可以做什么:使用宽松的数字格式来解析数字部分,获取解析器停止的位置,并使用其余的输入在映射中查找因子 例如: public static double convert(String number) { //this sho

是否有一种简单的方法可以使用纯Java或Apache commons库将工程符号(1.2K、120m等)中的数字解析为双倍值。我正在编写一个使用找到的代码的代码。我计划实施我自己的解决方案。目标是重用Java框架中包含的现有解决方案。最好的方法是什么

编写自己的解决方案时可以做什么:使用宽松的数字格式来解析数字部分,获取解析器停止的位置,并使用其余的输入在映射中查找因子

例如:

public static double convert(String number) {

  //this should be defined outside and is here just for simplicity reasons
  Map<String, Double> mapping = new HashMap<String, Double>();
  mapping.put( "k", 1000.0 );
  mapping.put( "m", 0.001 );

  //Use a specified Locale or otherwise the results would depend on your system locale
  NumberFormat f = NumberFormat.getNumberInstance( Locale.ENGLISH );
  ParsePosition p = new ParsePosition( 0 );

  Number n = f.parse( number, p  );
  String suffix = number.substring( p.getIndex() );
  Double factor = mapping.get( suffix );

  return n.doubleValue() * factor;
输出:

123453.0
-3.412

import java.util.regex.*;
枚举工程符号{
yocto('y',1e-24),
zepto('z',1e-21),
附件('a',1e-18),
飞秒级('f',1e-15),
微微('p',1e-12),
纳米('n',1e-9),
微(‘μ’,1e-6),
毫('m',1e-3),
单位(空,1e0),
千克('k',1e3),
百万('M',1e6),
千兆('G',1e9),
terra('T',1e12),
善待动物组织('P',1e15),
exa('E',1e18),
泽塔('Z',1e21),
约塔('Y',1e24);
最终字符符号;
最终双乘数;
专用工程符号(最终字符符号,最终双乘数){
这个符号=符号;
这个乘数=乘数;
}
公共字符getSymbol(){return symbol;}
public double getMultiplier(){return multiplier;}
私有静态最终模式正则表达式;
静止的{
最终StringBuffer=新StringBuffer();
buffer.append(“^([+-]?[1-9]\\d*\\.\\d*\.[+-]?0?\\.\\d+([”);
对于(最终工程符号e:values())
如果(如getSymbol()!=null)
append(例如getSymbol());
buffer.append(“]?)| E([+-]?[1-9]\\d*)$”;
REGEX=Pattern.compile(buffer.toString());
}
公共静态双重解析(最终字符串值){
最终匹配器m=正则表达式匹配器(值);
如果(!m.matches())
返回null;
Double result=Double.parseDouble(m.group(1));
如果(m.group(3)!=null)
返回结果*Math.pow(10,Integer.parseInt(m.group(3));
如果(m.group(2)=null)
返回结果;//单位
最后一个字符c=m.组(2).字符(0);
对于(最终工程符号e:values())
如果(如getSymbol()==c)
返回结果*e.getMultiplier();
返回null;
}
私有静态字符串doubleToString(最终双精度值){
如果(值==(长)值)
返回String.format(“%d”,(长)值);
返回字符串。格式(“%s”,值);
}
公共静态字符串到工程符号(
最终双值,
最终工程符号
){
if(表示法==null | |表示法==单位)
返回doubleToString(值);
返回doubleToString(value/notation.get乘数())+notation.getSymbol();
}
公共静态字符串到科学符号(
最终双值
){
最终长指数=(长)数学地板(数学log10(数学abs(值));
返回doubleToString(value/Math.pow(10,指数))+‘E’+指数;
}
公共静态字符串到工程符号(最终双精度值){
最终双abs=数学abs(数值);
双乘数;
对于(最终工程符号e:values())
{
乘数=e.getMultiplier();
如果(乘数<绝对值和绝对值<乘数*1000)
返回到工程符号(值e);
}
返回到科学符号(值);
}
公共静态void main(字符串[]args)引发java.lang.Exception
{
最终字符串[]解析测试={
“123万”,
“1.23E”,
“1.23E5”,
“1.23E+5”,
“-0.123E-28”
};
for(最终字符串测试:parseTests)
System.out.println(test+”解析为:“+Double.toString(parse(test))”;
最终双[]格式测试={
1234e18,
-12.34e-26,
100,
0.1
};
for(最终双重测试:格式测试)
System.out.println(Double.toString(test)+格式为“+toengineering notation(test));
}
}

我对该解决方案不满意
-您可能想详细说明为什么不满意。您能给我们一个示例,说明为什么该解决方案不适用于您的用例吗?您能从链接中包含代码片段吗?链接有随时间而中断的趋势。@brso05这就是为什么我问这样一个问题:是否有一种“非常简单的方法”我们现在就不会有IEEE754,对吗?谢谢,这样更好。不错,但这甚至可以处理
1.8701E123
?哦,我多么喜欢不合理的否决票;)@Shark很好,您可以单独处理这个特殊情况,例如,查找
e
,然后解析指数并调用
Math.pow(10,exponent)
。我的代码旨在提供一个起点,而不是一个完整的解决方案。除此之外,
xEy
不符合“工程符号”这个术语:@Shark刚刚又读了那篇文章,意识到
xEy
也是工程符号。我的错,对不起。
123453.0
-3.412
import java.util.regex.*;

enum EngineeringNotation{
  yocto( 'y', 1e-24 ),
  zepto( 'z', 1e-21 ),
  atta ( 'a', 1e-18 ),
  femto( 'f', 1e-15 ),
  pico ( 'p', 1e-12 ),
  nano ( 'n', 1e-9 ),
  micro( 'μ', 1e-6 ),
  milli( 'm', 1e-3 ),
  unit ( null, 1e0 ),
  kilo ( 'k', 1e3 ),
  mega ( 'M', 1e6 ),
  giga ( 'G', 1e9 ),
  terra( 'T', 1e12 ),
  peta ( 'P', 1e15 ),
  exa  ( 'E', 1e18 ),
  zetta( 'Z', 1e21 ),
  yotta( 'Y', 1e24 );

  final Character symbol;
  final double multiplier;

  private EngineeringNotation( final Character symbol, final double multiplier ){
    this.symbol     = symbol;
    this.multiplier = multiplier;
  }

  public Character getSymbol(){ return symbol; }
  public double getMultiplier(){ return multiplier; }

  private static final Pattern REGEX;

  static {
    final StringBuffer buffer = new StringBuffer();
    buffer.append( "^([+-]?[1-9]\\d*\\.?\\d*|[+-]?0?\\.\\d+)(?:([" );
    for ( final EngineeringNotation e : values() )
      if ( e.getSymbol() != null )
        buffer.append( e.getSymbol() );
    buffer.append( "]?)|E([+-]?[1-9]\\d*))$" );
    REGEX = Pattern.compile( buffer.toString() );
  }

  public static Double parse( final String value ){
    final Matcher m = REGEX.matcher( value );
    if ( !m.matches() )
        return null;
    Double result = Double.parseDouble( m.group(1) );
    if ( m.group(3) != null )
      return result * Math.pow( 10, Integer.parseInt( m.group(3) ) );
    if ( m.group(2) == null )
      return result; // Units
    final Character c = m.group(2).charAt(0);
    for ( final EngineeringNotation e : values() )
      if ( e.getSymbol() == c )
        return result * e.getMultiplier();
    return null;
  }

  private static String doubleToString( final double value ){
    if ( value == (long) value )
        return String.format( "%d", (long) value );
    return String.format( "%s", value );
  }

  public static String toEngineeringNotation(
      final double value,
      final EngineeringNotation notation
  ){
    if ( notation == null || notation == unit )
        return doubleToString( value );
    return doubleToString( value / notation.getMultiplier() ) + notation.getSymbol();
  }

  public static String toScientificNotation(
      final double value
  ){
    final long exponent = (long) Math.floor( Math.log10( Math.abs( value ) ) );
    return doubleToString( value / Math.pow( 10, exponent ) ) + 'E' + exponent;
  }

  public static String toEngineeringNotation( final double value ){
    final double abs = Math.abs( value );
    double multiplier;
    for ( final EngineeringNotation e : values() )
    {
      multiplier = e.getMultiplier();
      if ( multiplier < abs && abs < multiplier * 1000 )
        return toEngineeringNotation( value, e );
    }
    return toScientificNotation( value );
  }

  public static void main (String[] args) throws java.lang.Exception
  {
    final String[] parseTests = {
        "1.23M",
        "1.23E",
        "1.23E5",
        "1.23E+5",
        "-0.123E-28"
    };
    for ( final String test : parseTests )
      System.out.println( test + " parses to: " + Double.toString( parse( test ) ) );

    final double[] formatTests = {
        1234e18,
        -12.34e-26,
        100,
        0.1
    };

    for ( final double test : formatTests )
      System.out.println( Double.toString( test ) + " formats as " + toEngineeringNotation( test ) );
  }
}