内置数字

Page Contents

相关常见问题解答:您是否拥有 1,000,000 或 1,000,000(而不是 1000000)之类的东西,或者 3.14(而非 3,14)之类的东西?请参见thisthis常见问题解答条目,另请注意上面的c内置。

abs

Note:

自 FreeMarker 2.3.20 起存在此内置功能。

给出数字的绝对值。例如x?abs,如果x为-5,则求值为 5.

c(与数值一起使用时)

Note:

此内置功能自 FreeMarker 2.3.3 起存在。

此内置函数将数字转换为字符串,以表示“计算机语言”,而不是人类。也就是说,它使用编程语言过去使用的规则进行格式化,这与 FreeMarker 的所有语言环境和数字格式设置无关。它始终使用点作为小数点分隔符,并且绝不使用分组分隔符(例如 3,000,000),指数形式(例如 5E20),多余的前导或尾随 0-s(例如 03 或 1.0)或符号(例如 1)。它将在小数点后最多打印 16 位数字,因此绝对值小于 1E-16 的数字将显示为 0.此内置至关重要,因为默认值(如${x})将转换为带有适用于人类 Reader 的特定于语言环境(语言,国家/地区)的格式(例如 3000000 可能会打印为 3,000,000)。如果打印的数字不适合人类 Reader 使用(例如,用作 URL 一部分的数据库记录 ID,或用作 HTML 表单中的不可见字段值,或用于打印 CSS/JavaScript 数字 Literals),则必须内置此数字用于打印数字(即使用${x?c}而不是${x}),否则输出可能会中断,具体取决于当前数字的格式设置和语言环境(例如小数点不是点,而是在许多国家/地区是逗号)和值的数量(例如,将分隔符分组可能会“损坏”大数字)。

如果incompatible_improvements FreeMarker 配置设置设置为 2.3.24 或更高(如果设置为 2.3.20 或更高,并且您不在字符串 Literals 范围内),则此内置函数将返回"INF""-INF""NaN"表示正负无穷大和 IEEE 浮点非数字。这些是这些特殊值的 XML Schema 兼容表示。 (先前它返回了java.text.DecimalFormat对美国语言环境所做的操作,任何(通用)计算机语言都无法理解。)

请注意,此内置也适用于布尔值

is_infinite

Note:

自 FreeMarker 2.3.20 起存在此内置功能。

判断数字是否为浮点无穷大(根据 IEEE 754)。例如,someNumber?is_infinite取值为truefalse,具体取决于someNumber的值是否为无穷大。当然,如果基础数字不是浮点类型,则它将始终返回false

is_nan

Note:

自 FreeMarker 2.3.20 起存在此内置功能。

判断数字是否为浮点 NaN(根据 IEEE 754)。例如,someNumber?is_nan取值为truefalse,具体取决于someNumber的值是否为 NaN。当然,如果基础数字不是浮点类型,则它将始终返回false

lower_abc

Note:

此内置功能自 FreeMarker 2.3.22 开始存在。

123等转换为字符串"a""b""c"等。到达"z"时,它将像"aa""ab"等 continue。这与在电子表格应用程序的列标签中可以看到的逻辑相同(如 Excel 或 Calc)。允许的最小数字是1。没有上限。如果数字是0或更小或者不是整数,则模板处理将因错误中止。

Example:

<#list 1..30 as n>${n?lower_abc} </#list>

Prints:

a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad

另请参阅:upper_abc

圆,地板,天花板

Note:

自 FreeMarker 2.3.13 起存在舍入内置函数。

使用指定的舍入规则将数字转换为整数:

  • round:四舍五入到最接近的整数。如果数字以.5 结尾,则向上舍入(即朝正无穷大)

  • floor:将数字向下舍入(即朝负无穷大)

  • ceiling:向上舍入数字(即朝正无穷大)

Example:

<#assign testlist=[
  0, 1, -1, 0.5, 1.5, -0.5,
  -1.5, 0.25, -0.25, 1.75, -1.75]>
<#list testlist as result>
    ${result} ?floor=${result?floor} ?ceiling=${result?ceiling} ?round=${result?round}
</#list>

Prints:

0 ?floor=0 ?ceiling=0 ?round=0
    1 ?floor=1 ?ceiling=1 ?round=1
    -1 ?floor=-1 ?ceiling=-1 ?round=-1
    0.5 ?floor=0 ?ceiling=1 ?round=1
    1.5 ?floor=1 ?ceiling=2 ?round=2
    -0.5 ?floor=-1 ?ceiling=0 ?round=0
    -1.5 ?floor=-2 ?ceiling=-1 ?round=-1
    0.25 ?floor=0 ?ceiling=1 ?round=0
    -0.25 ?floor=-1 ?ceiling=0 ?round=0
    1.75 ?floor=1 ?ceiling=2 ?round=2
    -1.75 ?floor=-2 ?ceiling=-1 ?round=-2

这些内置函数可能在分页操作等中有用。如果只想以四舍五入形式显示数字,则应该使用string built-innumber_format setting

字符串(与数字值一起使用时)

将数字转换为字符串。它以最简单的形式(expression?string)使用程序员通过number_formatlocale配置设置指定的默认格式。您也可以使用此内置显式指定数字格式,如稍后所示。

有四种 sched 义的数字格式:computercurrencynumberpercent。它们的确切含义是特定于语言环境(国籍)的,并且由 Java 平台安装(而不是 FreeMarker)控制,除了computer除外,后者使用与内置的 c相同的格式。也可以有程序员定义的格式,其名称以@开头(程序员在这里看到更多...)。您可以使用以下 sched 义格式:

<#assign x=42>
${x}
${x?string}  <#-- the same as ${x} -->
${x?string.number}
${x?string.currency}
${x?string.percent}
${x?string.computer}

如果您的语言环境是美国英语,则将打印:

42
42
42
$42.00
4,200%
42

前三个表达式的输出相同,因为前两个表达式使用默认格式,此处为“数字”。您可以使用以下设置更改此默认设置:

<#setting number_format="currency">
<#assign x=42>
${x}
${x?string}  <#-- the same as ${x} -->
${x?string.number}
${x?string.currency}
${x?string.percent}

现在将输出:

$42.00
$42.00
42
$42.00
4,200%

由于默认数字格式设置为“货币”。

您还可以引用在配置 FreeMarker(程序员在这里看到更多)时定义的命名自定义格式,例如:

${x?string.@price}
${x?string.@weight}

自定义格式的名称为“价格”和“重量”。这样,模板可以只引用应用程序域的含义,并且可以在模板外部的单个中心位置指定确切格式。 (程序员可以阅读有关在这里定义这样的命名格式...的信息)

除了命名格式,您可以使用Java 十进制数字格式语法(带有某些 FreeMarkerextensions; see later)直接指定数字格式模式:

<#assign x = 1.234>
${x?string["0"]}
${x?string["0.#"]}
${x?string["0.##"]}
${x?string["0.###"]}
${x?string["0.####"]}

${1?string["000.00"]}
${12.1?string["000.00"]}
${123.456?string["000.00"]}

${1.2?string["0"]}
${1.8?string["0"]}
${1.5?string["0"]} <-- 1.5, rounded towards even neighbor
${2.5?string["0"]} <-- 2.5, rounded towards even neighbor

${12345?string["0.##E0"]}
1
1.2
1.23
1.234
1.234

001.00
012.10
123.46

1
2
2 <-- 1.5, rounded towards even neighbor
2 <-- 2.5, rounded towards even neighbor

1.23E4

请注意,就像在 FreeMarker foo.bar中等效于foo["bar"]一样,您也可以将x?string.currency写为x?string["currency"],但是当然这是不切实际的。但是在上面的示例中,我们必须使用方括号语法,因为在点运算符之后,语法上不允许使用涉及的字符(数字,点,#)。

出于历史原因,您也可以编写x?string("0.#")之类的东西,它与x?string["0.#"]完全一样。

按照财务和统计惯例,默认情况下,四舍五入是按照所谓的半均数规则进行的,这意味着朝着最近的“邻居”四舍五入,除非两个邻居都是等距的,在这种情况下,会朝着偶数邻居四舍五入。在上面的示例中,如果您将 1.5 和 2.5 的舍入都可见,因为它们都舍入为 2,因为 2 是偶数,而 1 和 3 是奇数,所以这在上例中可见。另一种流行的舍入规则(通常在邻居等距时将其舍入(因此将 2.5 舍入为 3))被称为 Half-up 规则,可以将其激活为described later

如之前显示的 sched 义格式所示,可以在模板中设置数字的默认格式:

<#setting number_format="0.##">
${1.234}
1.23

还可以使用 FreeMarker API(例如Configuration.setNumberFormat(String))在模板外部指定默认数字格式。

请注意,由于数字格式对区域设置敏感,因此区域设置在格式设置中也起作用:

<#setting number_format=",##0.00">
<#setting locale="en_US">
US people write:     ${12345678}
<#setting locale="de_DE">
German people write: ${12345678}
US people write:     12,345,678.00
German people write: 12.345.678,00

Java 十进制扩展格式

Note:

您至少需要 FreeMarker 2.3.24 才能起作用。在此之前,扩展的 Java 十进制格式部分仅被java.text.DecimalFormat忽略。

FreeMarker 通过附加选项扩展了 Java 十进制格式模式。这些选项是名称/值对,在格式字符串末尾的两个分号(;;)后指定,或者如果您使用的是负数模式(该模式与常规模式用分号分隔,例如"0.0;minus 0.0"),则仅在后面一分号。例如:

Standard decimal format: ${10002.5?string[",000"]}
Extended decimal format: ${10002.5?string[",000;; roundingMode=halfUp groupingSeparator=_"]}
Standard decimal format: 10,002
Extended decimal format: 10_003

Warning!

一个很容易犯的错误就是只使用一个分号而不是两个。甚至不会导致错误,因为java.text.DecimalFormat认为您刚刚为负数指定了一些奇怪的格式。因此,请记住使用两个分号。

上面,我们以扩展的十进制格式指定了上半舍入模式和组分隔符"_"。所有选项的表如下(请注意,它们是由java.text.DecimalFormatjava.text.DecimalFormatSymbols定义的,而不是由 FreeMarker 定义的):

Name含义/价值
roundingMode该值为updownceilingfloorhalfUphalfDownhalfEvenunnecessary之一。大多数人在学校学习的行为是halfUp,但是 Java 默认值是halfEven(也称为银行家四舍五入)。 (有关说明,请参见java.math.RoundingMode API。)
multiplier自 2.3.29 起; multipier自 2.3.24 起乘以该整数后,将显示该数字。
decimalSeparator将整数部分与小数部分分开的字符(例如3.14中的".")。
monetaryDecimalSeparator当模式包含使其成为货币格式的部分时,将使用它代替decimalSeparator。 (有关详情,请参见Java 十进制数字格式文档。)
groupingSeparator用于对整数部分进行分组的单个字符(如1,000,000中的",")请注意,通过在模式中使用","可以打开分组,如前面的示例所示。如果未打开,则此选项将无效。
exponentSeparator该字符串(任意长度)用于将指数与之前的部分分开。 (如1.23E6中的"E")。仅在模式指定"0.##E0"之类的指数(也称为科学)格式时才具有可见效果。
minusSign用作减号的单个字符(例如-1中的"-")。
infinity用于显示无穷大的字符串(任意长度)。
nan用于显示非数字(NaN)的字符串(任意长度)。
percent用作百分号的单个字符(例如50%中的"%")。仅在模式包含%时才可见。
perMill用作铣削符号的单个字符(例如50021‰中的"‰")。仅在模式包含时才可见。
zeroDigit10 个字符范围(字符代码)中的第一个字符,包含要使用的数字。例如,如果这是A,那么 1 将是B,2 将是C,依此类推。
currencyCode货币 ISO 4217 代码。仅在模式包含使其成为货币格式的部分时才有效。在 Java 安装中指定不是 ISO 4217 已知代码的代码是错误的。
currencySymbol货币符号;显示模式中存在本地化货币名称的位置。覆盖根据currencyCode确定的符号。

关于选项的语法:

  • 选项名称和值由等号(=)分隔。

  • 选项由空格和/或可选的逗号(,)分隔

  • 选项值可以用撇号(')或普通引号(")进行引号,例如exponentSeparator='*10^'exponentSeparator="*10^"。如果值本身必须包含用于引号的字符,则必须 Importing 两次(例如infinity='It''s infinite',但您也可以编写infinity="It's infinite")。反斜杠没有特殊含义。

  • 非字符串值不能用引号引起来。仅当字符串包含标点符号或空格或任何其他非字母非数字非"_""$"字符时,才必须用引号引起来。因此,例如roundingMode=downroundingMode="down"都是合法的。

upper_abc

Note:

此内置功能自 FreeMarker 2.3.22 开始存在。

lower_abc相同,但转换为大写字母,例如"A""B""C",…,"AA""AB"等。