如何在 Bash 中比较两个浮点数?

发布于 2024-12-23 06:39:19 字数 317 浏览 3 评论 0 原文

我正在努力比较 Bash 脚本中的两个浮点数。我有两个变量,例如

let num1=3.17648e-22
let num2=1.5

现在,我只想对这两个数字进行简单的比较:

st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
  echo -e "$num1 < $num2"
else
  echo -e "$num1 >= $num2"
fi

不幸的是,我在正确处理可以是“电子格式”的 num1 时遇到一些问题。

I am trying hard to compare two floating point numbers within a Bash script. I have two variables, e.g.

let num1=3.17648e-22
let num2=1.5

Now, I just want do a simple comparison of these two numbers:

st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
  echo -e "$num1 < $num2"
else
  echo -e "$num1 >= $num2"
fi

Unfortunately, I have some problems with the right treatment of the num1 which can be of the "e-format".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

笑脸一如从前 2024-12-30 06:39:19

更方便

使用 Bash 的数字上下文可以更方便地完成此操作:

if (( $(echo "$num1 > $num2" |bc -l) )); then
  …
fi

解释

通过基本计算器命令 bc 进行管道传输返回 1 或 0。

选项 -l 相当于 --mathlib;它加载标准数学库。

将整个表达式括在双括号 (( )) 之间会将这些值分别转换为 true 或 false。

请确保安装了 bc 基本计算器软件包。

警告:指数表示法应写为 *10^;不是E,也不是e

例如:

$ echo "1*10^3==1000" |bc
1

此处

$ echo "1E3==1000" |bc
0

讨论了克服此 bc 限制的策略。

More conveniently

This can be done more conveniently using Bash's numeric context:

if (( $(echo "$num1 > $num2" |bc -l) )); then
  …
fi

Explanation

Piping through the basic calculator command bc returns either 1 or 0.

The option -l is equivalent to --mathlib; it loads the standard math library.

Enclosing the whole expression between double parenthesis (( )) will translate these values to respectively true or false.

Please, ensure that the bc basic calculator package is installed.

Caveat: Exponential notation should be written as *10^; not E, nor e.

For example:

$ echo "1*10^3==1000" |bc
1

Whereas

$ echo "1E3==1000" |bc
0

Strategies to overcome this bc limitation are discussed here.

倾城°AllureLove 2024-12-30 06:39:19

Bash 仅处理整数数学,但您可以使用 bc 命令,如下所示:

$ num1=3.17648E-22
$ num2=1.5
$ echo $num1'>'$num2 | bc -l
0
$ echo $num2'>'$num1 | bc -l
1

请注意,指数符号必须大写。

Bash handles only integer maths, but you can use the bc command as follows:

$ num1=3.17648E-22
$ num2=1.5
$ echo $num1'>'$num2 | bc -l
0
$ echo $num2'>'$num1 | bc -l
1

Note that the exponent sign must be uppercase.

梨涡 2024-12-30 06:39:19

您可以将 AWK 与 Bash if 条件结合使用:

if awk "BEGIN {exit !($d1 >= $d2)}"; then
    echo "yes"
else
    echo "no"
fi

You can use AWK combined with a Bash if condition:

if awk "BEGIN {exit !($d1 >= $d2)}"; then
    echo "yes"
else
    echo "no"
fi
雾里花 2024-12-30 06:39:19

一个纯 Bash 解决方案,用于比较没有指数表示法、前导零或尾随零的浮点数:

if [ ${FOO%.*} -eq ${BAR%.*} ] && [ ${FOO#*.} \> ${BAR#*.} ] || [ ${FOO%.*} -gt ${BAR%.*} ]; then
  echo "${FOO} > ${BAR}";
else
  echo "${FOO} <= ${BAR}";
fi

逻辑运算符的顺序 很重要。整数部分作为数字进行比较,小数部分作为字符串进行比较。使用 这个方法

它不会将浮点数与整数(不带点)进行比较。

A pure Bash solution for comparing floats without exponential notation, leading or trailing zeros:

if [ ${FOO%.*} -eq ${BAR%.*} ] && [ ${FOO#*.} \> ${BAR#*.} ] || [ ${FOO%.*} -gt ${BAR%.*} ]; then
  echo "${FOO} > ${BAR}";
else
  echo "${FOO} <= ${BAR}";
fi

The order of logical operators matters. Integer parts are compared as numbers and fractional parts are intentionally compared as strings. Variables are split into integer and fractional parts using this method.

It won't compare floats with integers (without dot).

半衾梦 2024-12-30 06:39:19

对于非整数数学,最好使用 AWK 。您可以使用这个 Bash 实用函数:

numCompare() {
   awk -v n1="$1" -v n2="$2" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}

并将其调用为:

numCompare 5.65 3.14e-22
5.65 >= 3.14e-22

numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22

numCompare 3.145678 3.145679
3.145678 < 3.145679

It's better to use AWK for noninteger mathematics. You can use this Bash utility function:

numCompare() {
   awk -v n1="$1" -v n2="$2" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}

And call it as:

numCompare 5.65 3.14e-22
5.65 >= 3.14e-22

numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22

numCompare 3.145678 3.145679
3.145678 < 3.145679
没︽人懂的悲伤 2024-12-30 06:39:19

比较软件包版本的数字时要小心,例如检查 grep 2.20 是否大于版本 2.6:

$ awk 'BEGIN { print (2.20 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.2 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.60 == 2.6) ? "YES" : "NO" }'
YES

我用这样的 shell/AWK 函数解决了这样的问题:

# Get version of GNU tool
toolversion() {
    local prog="$1" operator="$2" value="$3" version

    version=$($prog --version | awk '{print $NF; exit}')

    awk -vv1="$version" -vv2="$value" 'BEGIN {
        split(v1, a, /\./); split(v2, b, /\./);
        if (a[1] == b[1]) {
            exit (a[2] '$operator' b[2]) ? 0 : 1
        }
        else {
            exit (a[1] '$operator' b[1]) ? 0 : 1
        }
    }'
}

if toolversion grep '>=' 2.6; then
   # Do something awesome
fi

Beware when comparing numbers that are package versions, like checking if grep 2.20 is greater than version 2.6:

$ awk 'BEGIN { print (2.20 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.2 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.60 == 2.6) ? "YES" : "NO" }'
YES

I solved such problems with such a shell/AWK function:

# Get version of GNU tool
toolversion() {
    local prog="$1" operator="$2" value="$3" version

    version=$($prog --version | awk '{print $NF; exit}')

    awk -vv1="$version" -vv2="$value" 'BEGIN {
        split(v1, a, /\./); split(v2, b, /\./);
        if (a[1] == b[1]) {
            exit (a[2] '$operator' b[2]) ? 0 : 1
        }
        else {
            exit (a[1] '$operator' b[1]) ? 0 : 1
        }
    }'
}

if toolversion grep '>=' 2.6; then
   # Do something awesome
fi
无法回应 2024-12-30 06:39:19

支持所有可能的符号的解决方案,包括具有大写和小写指数的科学记数法(例如,12.00e4):

if (( $(bc -l <<< "${value1/e/E} < ${value2/e/E}") ))
then
    echo "$value1 is smaller than $value2"
fi 

A solution that supports all possible notations, including the scientific notation with both uppercase and lowercase exponents (e.g., 12.00e4):

if (( $(bc -l <<< "${value1/e/E} < ${value2/e/E}") ))
then
    echo "$value1 is smaller than $value2"
fi 
若言繁花未落 2024-12-30 06:39:19

当然,如果您不需要真正的浮点算术,只需对美元值进行算术,其中总是恰好有两位小数,您可以删除点(实际上乘以 100)并比较结果整数。

if [[ $((10#${num1/.})) < $((10#${num2/.})) ]]; then
    ...

这显然要求您确保两个值具有相同的小数位数。

Of course, if you don't need really floating-point arithmetic, just arithmetic on e.g. dollar values where there are always exactly two decimal digits, you might just drop the dot (effectively multiplying by 100) and compare the resulting integers.

if [[ $((10#${num1/.})) < $((10#${num2/.})) ]]; then
    ...

This obviously requires you to be sure that both values have the same number of decimal places.

横笛休吹塞上声 2024-12-30 06:39:19

请检查下面编辑的代码:

#!/bin/bash

export num1=(3.17648*e-22)
export num2=1.5

st=$((`echo "$num1 < $num2"| bc`))
if [ $st -eq 1 ]
  then
    echo -e "$num1 < $num2"
  else
    echo -e "$num1 >= $num2"
fi

这效果很好。

Please check the below edited code:

#!/bin/bash

export num1=(3.17648*e-22)
export num2=1.5

st=$((`echo "$num1 < $num2"| bc`))
if [ $st -eq 1 ]
  then
    echo -e "$num1 < $num2"
  else
    echo -e "$num1 >= $num2"
fi

This works well.

蓝戈者 2024-12-30 06:39:19
num1=0.555
num2=2.555


if [ `echo "$num1>$num2"|bc` -eq 1 ]; then
       echo "$num1 is greater then $num2"
else
       echo "$num2 is greater then $num1"
fi
num1=0.555
num2=2.555


if [ `echo "$num1>$num2"|bc` -eq 1 ]; then
       echo "$num1 is greater then $num2"
else
       echo "$num2 is greater then $num1"
fi
萌酱 2024-12-30 06:39:19

AWK 和类似的工具(我正盯着你 sed ...)应该被扔进旧项目的垃圾箱,其中的代码每个人都不敢碰,因为它是用一种从不读的语言编写的。

或者您是一个相对罕见的项目,需要优先考虑 CPU 使用优化而不是代码维护优化……在这种情况下,请继续。

如果没有,那么,只需使用可读且明确的东西,例如 Python。你的同事和未来的自己都会感谢你。您可以像所有其他代码一样将 Python 代码与 Bash 内联使用。

num1=3.17648E-22
num2=1.5
if python -c "exit(0 if $num1 < $num2 else 1)"; then
    echo "yes, $num1 < $num2"
else
    echo "no, $num1 >= $num2"
fi

AWK and tools like it (I'm staring at you sed...) should be relegated to the dustbin of old projects, with code that everyone is too afraid to touch since it was written in a read-never language.

Or you're the relatively rare project that needs to prioritize CPU usage optimization over code maintenance optimization... in which case, carry on.

If not, though, instead just use something readable and explicit, such as Python. Your fellow coders and future self will thank you. You can use Python code inline with Bash just like all the others.

num1=3.17648E-22
num2=1.5
if python -c "exit(0 if $num1 < $num2 else 1)"; then
    echo "yes, $num1 < $num2"
else
    echo "no, $num1 >= $num2"
fi
清晨说晚安 2024-12-30 06:39:19

我使用了这里的答案并将它们放入一个函数中。您可以这样使用它:

is_first_floating_number_bigger 1.5 1.2
result="${__FUNCTION_RETURN}"

在本例中,一旦调用,echo $result 将为 1,否则为 0

函数:

is_first_floating_number_bigger () {
    number1="$1"
    number2="$2"

    [ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
    result=$?
    if [ "$result" -eq 0 ]; then result=1; else result=0; fi

    __FUNCTION_RETURN="${result}"
}

或者带有调试输出的版本:

is_first_floating_number_bigger () {
    number1="$1"
    number2="$2"

    echo "... is_first_floating_number_bigger: comparing ${number1} with ${number2} (to check if the first one is bigger)"

    [ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
    result=$?
    if [ "$result" -eq 0 ]; then result=1; else result=0; fi

    echo "... is_first_floating_number_bigger: result is: ${result}"

    if [ "$result" -eq 0 ]; then
        echo "... is_first_floating_number_bigger: ${number1} is not bigger than ${number2}"
    else
        echo "... is_first_floating_number_bigger: ${number1} is bigger than ${number2}"
    fi

    __FUNCTION_RETURN="${result}"
}

只需将函数保存在单独的 .sh 文件中,并像这样包含它:

. /path/to/the/new-file.sh

I used the answers from here and put them in a function. You can use it like this:

is_first_floating_number_bigger 1.5 1.2
result="${__FUNCTION_RETURN}"

Once called, echo $result will be 1 in this case, otherwise 0.

The function:

is_first_floating_number_bigger () {
    number1="$1"
    number2="$2"

    [ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
    result=$?
    if [ "$result" -eq 0 ]; then result=1; else result=0; fi

    __FUNCTION_RETURN="${result}"
}

Or a version with debug output:

is_first_floating_number_bigger () {
    number1="$1"
    number2="$2"

    echo "... is_first_floating_number_bigger: comparing ${number1} with ${number2} (to check if the first one is bigger)"

    [ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
    result=$?
    if [ "$result" -eq 0 ]; then result=1; else result=0; fi

    echo "... is_first_floating_number_bigger: result is: ${result}"

    if [ "$result" -eq 0 ]; then
        echo "... is_first_floating_number_bigger: ${number1} is not bigger than ${number2}"
    else
        echo "... is_first_floating_number_bigger: ${number1} is bigger than ${number2}"
    fi

    __FUNCTION_RETURN="${result}"
}

Just save the function in a separated .sh file and include it like this:

. /path/to/the/new-file.sh
风为裳 2024-12-30 06:39:19

为了简单和清晰起见,只需使用 AWK 进行计算,因为它是标准 Unix 工具,因此可能以 bc 并且在语法上更容易使用。

对于这个问题:

$ cat tst.sh
#!/bin/bash

num1=3.17648e-22
num2=1.5

awk -v num1="$num1" -v num2="$num2" '
BEGIN {
    print "num1", (num1 < num2 ? "<" : ">="), "num2"
}
'

$ ./tst.sh
num1 < num2

对于作为该问题的重复项而关闭的另一个问题:

$ cat tst.sh
#!/bin/bash

read -p "Operator: " operator
read -p "First number: " ch1
read -p "Second number: " ch2

awk -v ch1="$ch1" -v ch2="$ch2" -v op="$operator" '
BEGIN {
    if ( ( op == "/" ) && ( ch2 == 0 ) ) {
        print "Nope..."
    }
    else {
        print ch1 '"$operator"' ch2
    }
}
'

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 2
2.25

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 0
Nope...

我将其发布为'4.5:语法错误:算术运算符无效(错误标记为“.5”)' - 但代码似乎仍然有效。为什么?当它作为这个问题的重复项被关闭时,所以这里也适用。

For simplicity and clarity, just use AWK for the calculations as it's a standard Unix tool and so just as likely to be present as bc and much easier to work with syntactically.

For this question:

$ cat tst.sh
#!/bin/bash

num1=3.17648e-22
num2=1.5

awk -v num1="$num1" -v num2="$num2" '
BEGIN {
    print "num1", (num1 < num2 ? "<" : ">="), "num2"
}
'

$ ./tst.sh
num1 < num2

And for that other question that was closed as a duplicate of this one:

$ cat tst.sh
#!/bin/bash

read -p "Operator: " operator
read -p "First number: " ch1
read -p "Second number: " ch2

awk -v ch1="$ch1" -v ch2="$ch2" -v op="$operator" '
BEGIN {
    if ( ( op == "/" ) && ( ch2 == 0 ) ) {
        print "Nope..."
    }
    else {
        print ch1 '"$operator"' ch2
    }
}
'

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 2
2.25

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 0
Nope...

I was posting this as an answer to '4.5: syntax error: invalid arithmetic operator (error token is ".5")' - but the code still seems to work. Why? when it got closed as a duplicate of this question, so here it is as it applies here too.

淡写薰衣草的香 2024-12-30 06:39:19

此脚本可能会帮助我检查已安装的 Grails 版本是否更高超过最低要求。

#!/bin/bash

min=1.4
current=`echo $(grails --version | head -n 2 | awk '{print $NF}' | cut -c 1-3)`

if [ 1 -eq `echo "${current} < ${min}" | bc` ]
then
    echo "Yo, you have an older version of Grails."
else
    echo "Hurray, you have the latest version"
fi

This script may help where I'm checking if the installed Grails version is greater than the minimum required.

#!/bin/bash

min=1.4
current=`echo $(grails --version | head -n 2 | awk '{print $NF}' | cut -c 1-3)`

if [ 1 -eq `echo "${current} < ${min}" | bc` ]
then
    echo "Yo, you have an older version of Grails."
else
    echo "Hurray, you have the latest version"
fi
阳光的暖冬 2024-12-30 06:39:19

使用 KornShell。在 Bash 中,您可能需要单独比较小数部分:

#!/bin/ksh
X=0.2
Y=0.2
echo $X
echo $Y

if [[ $X -lt $Y ]]
then
     echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
     echo "X is greater than Y"
elif [[ $X -eq $Y ]]
then
     echo "X is equal to Y"
fi

Use KornShell. In Bash you may have to compare the decimal part separately:

#!/bin/ksh
X=0.2
Y=0.2
echo $X
echo $Y

if [[ $X -lt $Y ]]
then
     echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
     echo "X is greater than Y"
elif [[ $X -eq $Y ]]
then
     echo "X is equal to Y"
fi
分开我的手 2024-12-30 06:39:19

使用这个:

VAL_TO_CHECK="1.00001"
if [ $(awk '{printf($1 >= $2) ? 1 : 0}' <<<" $VAL_TO_CHECK 1 ") -eq 1 ] ; then
    echo "$VAL_TO_CHECK >= 1"
else
    echo "$VAL_TO_CHECK < 1"
fi

Use this:

VAL_TO_CHECK="1.00001"
if [ $(awk '{printf($1 >= $2) ? 1 : 0}' <<<" $VAL_TO_CHECK 1 ") -eq 1 ] ; then
    echo "$VAL_TO_CHECK >= 1"
else
    echo "$VAL_TO_CHECK < 1"
fi
蛮可爱 2024-12-30 06:39:19

使用 bashj(一个支持 Java 的 Bash 变体),您只需编写(并且它是< /em> 易于阅读):

#!/usr/bin/bashj

#!java
static int doubleCompare(double a,double b) {return((a>b) ? 1 : (a<b) ? -1 : 0);}

#!bashj
num1=3.17648e-22
num2=1.5
comp=j.doubleCompare($num1,$num2)
if [ $comp == 0 ] ; then echo "Equal" ; fi
if [ $comp == 1 ] ; then echo "$num1 > $num2" ; fi
if [ $comp == -1 ] ; then echo "$num2 > $num1" ; fi

当然,bashj Bash/Java 混合提供了更多...

Using bashj, a Bash mutant with Java support, you just write (and it is easy to read):

#!/usr/bin/bashj

#!java
static int doubleCompare(double a,double b) {return((a>b) ? 1 : (a<b) ? -1 : 0);}

#!bashj
num1=3.17648e-22
num2=1.5
comp=j.doubleCompare($num1,$num2)
if [ $comp == 0 ] ; then echo "Equal" ; fi
if [ $comp == 1 ] ; then echo "$num1 > $num2" ; fi
if [ $comp == -1 ] ; then echo "$num2 > $num1" ; fi

Of course, the bashj Bash/Java hybridation offers much more...

疑心病 2024-12-30 06:39:19

一个非常简单的 Perl 解决方案:

$ num1=3.2E8
$ num2=2.5E9
$ perl -e "print $num2 > $num1? 'true' : 'false', qq(\n);"
true
$ perl -e "print $num2 < $num1? 'true' : 'false', qq(\n);"
false

这证明 Perl 确实理解科学数字表示的“E”表示法:

$ perl -e "print $num1, qq(\n);"
320000000

如果您的 shell 脚本中需要“if”语句,请在 perl 中使用 exit 命令:

$ if perl -e "exit ($num1 > $num2? 0 : 1);"; then echo true; else echo false; fi
false

请注意,在 shell 脚本中,命令返回0 表示成功,并通过“if”条件(因此执行 if 子句)。任何其他非零返回值都意味着失败。

A very simple perl solution:

$ num1=3.2E8
$ num2=2.5E9
$ perl -e "print $num2 > $num1? 'true' : 'false', qq(\n);"
true
$ perl -e "print $num2 < $num1? 'true' : 'false', qq(\n);"
false

This proves that perl really understands the 'E' notation for scientific numerical representation:

$ perl -e "print $num1, qq(\n);"
320000000

If you need a 'if' statment in your shell script, use exit command in perl:

$ if perl -e "exit ($num1 > $num2? 0 : 1);"; then echo true; else echo false; fi
false

Note that in shell script, a command returning 0 is a success, and passes the 'if' condition (so the if-clause is executed). Any other non-zero return values means a failure.

╰◇生如夏花灿烂 2024-12-30 06:39:19

有一种简单的方法,它比 AWK 快一点,并且不需要安装 bc。它利用sort对浮点数进行排序的能力:

A=1280.4
B=9.325
LOW=$(sort -n <<< "$A"

当然,它不适用于相等的数字

\n'"$B" | head -1) if [[ "$LOW" == "$A" ]]; then echo "A <= B" else echo "A >= B" fi

当然,它不适用于相等的数字

There's one simple approach which is a bit faster than AWK and does not require bc to be installed. It leverages sort's ability to sort float numbers:

A=1280.4
B=9.325
LOW=$(sort -n <<< "$A"

Of course, it does not work for numbers that are equal.

\n'"$B" | head -1) if [[ "$LOW" == "$A" ]]; then echo "A <= B" else echo "A >= B" fi

Of course, it does not work for numbers that are equal.

一身软味 2024-12-30 06:39:19

只需将 echo 替换为 printf (它理解浮点数):

st=$(  printf '%50G < %50G\n' "$num1" "$num2" | bc -l  )

Just replace the echo with a printf (it understands floats):

st=$(  printf '%50G < %50G\n' "$num1" "$num2" | bc -l  )
断肠人 2024-12-30 06:39:19

单行解决方案

假设您有两个变量 AB

echo "($A > $B) * $B + ($A < $B) * $A" | bc

A one-liner solution

Suppose you have two variables A and B,

echo "($A > $B) * $B + ($A < $B) * $A" | bc
﹏半生如梦愿梦如真 2024-12-30 06:39:19

这是一种基于 gawk+GMP 的方法,可以考虑更广泛的潜在输入:

 echo " 5.65e-23 3.14e-22\n
        5.65 3.14e-2203\n
        3.145678 3.145679\n
        3.25353E+9293 325353e9288\n
        3.14159e+200000000001 3.1415899999999999999999E200000000001\n
        100000 100000.0\n
             4096 4096" \
                         \
 | gawk -v PREC=9999999 -nMbe '
  
   NF+=OFS=sprintf(" %s ",
          (+($!_=sprintf("%24s",$!_)<+$NF) \
     ? "<" \
        : (+$NF<+$!_) \
     ? ">" \
        : (int(+$!_)==(__=int(+$NF)))*\
          (__==+$NF)*index($!_,$NF  )  \
     ? "=" \
         : "\342\211\210")' | ecp 
 
                5.65e-23 < 3.14e-22
                    5.65 > 3.14e-2203
                3.145678 < 3.145679
           3.25353E+9293 ≈ 325353e9288
   3.14159e+200000000001 ≈ 3.1415899999999999999999E200000000001
                  100000 ≈ 100000.0
                    4096 = 4096
 

对于更明确的情况,它会给您一个

  • 小于 << 的明确答案。 code>,
  • 大于 >,或
  • 完全等于 =(目前纯整数情况)

当它相对不明确时,它输出 Unicode 人物U+2248 ≈ ALMOST EQUAL TO 而不是不惜一切代价尝试解决它。

大多数时候您不需要 1000 万的 PREC;像 PREC = 32767 这样的东西对于人们通常遇到的大多数场景来说已经足够好了。

Here's a gawk+GMP based approach to account for a broader range of potential input :

 echo " 5.65e-23 3.14e-22\n
        5.65 3.14e-2203\n
        3.145678 3.145679\n
        3.25353E+9293 325353e9288\n
        3.14159e+200000000001 3.1415899999999999999999E200000000001\n
        100000 100000.0\n
             4096 4096" \
                         \
 | gawk -v PREC=9999999 -nMbe '
  
   NF+=OFS=sprintf(" %s ",
          (+($!_=sprintf("%24s",$!_)<+$NF) \
     ? "<" \
        : (+$NF<+$!_) \
     ? ">" \
        : (int(+$!_)==(__=int(+$NF)))*\
          (__==+$NF)*index($!_,$NF  )  \
     ? "=" \
         : "\342\211\210")' | ecp 
 
                5.65e-23 < 3.14e-22
                    5.65 > 3.14e-2203
                3.145678 < 3.145679
           3.25353E+9293 ≈ 325353e9288
   3.14159e+200000000001 ≈ 3.1415899999999999999999E200000000001
                  100000 ≈ 100000.0
                    4096 = 4096
 

For more clear-cut cases, it'll give you back a definitive answer of

  • less than <,
  • greater than >, or
  • exactly equal to = (purely integer cases, for now)

When it's relatively ambiguous, it outputs the Unicode character U+2248 ≈ ALMOST EQUAL TO instead of attempting to resolve it at all cost.

Most of the time you won't need PREC of 10-million; something like PREC = 32767 is good enough for most scenarios one encounters on a typical basis.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文