(Added some tests for ArithmeticEngine.toNumber, and ?number)
diff --git a/src/main/java/freemarker/core/ArithmeticEngine.java b/src/main/java/freemarker/core/ArithmeticEngine.java
index e6be82b..468f5e4 100644
--- a/src/main/java/freemarker/core/ArithmeticEngine.java
+++ b/src/main/java/freemarker/core/ArithmeticEngine.java
@@ -623,7 +623,7 @@
             return new BigDecimal(num.toString());
         } catch (NumberFormatException e) {
             if (NumberUtil.isInfinite(num)) {
-                throw new NumberFormatException("It's impossible to convert an infinte value ("
+                throw new NumberFormatException("It's impossible to convert an infinite value ("
                         + num.getClass().getSimpleName() + " " + num + ") to BigDecimal.");
             }
             // The exception message is useless, so we add a new one:
diff --git a/src/test/java/freemarker/core/BigDecimalArithmeticEngineTest.java b/src/test/java/freemarker/core/ArithmeticEngineTest.java
similarity index 74%
rename from src/test/java/freemarker/core/BigDecimalArithmeticEngineTest.java
rename to src/test/java/freemarker/core/ArithmeticEngineTest.java
index d6db2f7..fc22d58 100644
--- a/src/test/java/freemarker/core/BigDecimalArithmeticEngineTest.java
+++ b/src/test/java/freemarker/core/ArithmeticEngineTest.java
@@ -25,9 +25,10 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 
+import org.hamcrest.Matchers;
 import org.junit.Test;
 
-public class BigDecimalArithmeticEngineTest {
+public class ArithmeticEngineTest {
 
     @Test
     public void compareNumbersZeroTest() {
@@ -94,4 +95,32 @@
         }
     }
 
+    @Test
+    public void toNumberTest() {
+        for (ArithmeticEngine arithmeticEngine : new ArithmeticEngine[]{BIGDECIMAL_ENGINE, CONSERVATIVE_ENGINE}) {
+            assertEquals(Double.POSITIVE_INFINITY, arithmeticEngine.toNumber("INF"));
+            assertEquals(Double.NEGATIVE_INFINITY, arithmeticEngine.toNumber("-INF"));
+            assertEquals(Double.NEGATIVE_INFINITY, arithmeticEngine.toNumber("-Infinity"));
+            assertEquals(Double.POSITIVE_INFINITY, arithmeticEngine.toNumber("Infinity"));
+            Number nan = arithmeticEngine.toNumber("NaN");
+            assertThat(nan, Matchers.instanceOf(Double.class));
+            assertTrue(Double.isNaN((double) nan));
+        }
+
+        assertEquals(new BigDecimal("1234567"), BIGDECIMAL_ENGINE.toNumber("1234567"));
+        assertEquals(Integer.valueOf("1234567"), CONSERVATIVE_ENGINE.toNumber("1234567"));
+
+        assertEquals(new BigDecimal("12345678901234"), BIGDECIMAL_ENGINE.toNumber("12345678901234"));
+        assertEquals(12345678901234L, CONSERVATIVE_ENGINE.toNumber("12345678901234"));
+
+        assertEquals(new BigDecimal("12345678901234567890"), BIGDECIMAL_ENGINE.toNumber("12345678901234567890"));
+        assertEquals(new BigInteger("12345678901234567890"), CONSERVATIVE_ENGINE.toNumber("12345678901234567890"));
+
+        assertEquals(new BigDecimal("1.9"), BIGDECIMAL_ENGINE.toNumber("1.9"));
+        assertEquals(1.9, CONSERVATIVE_ENGINE.toNumber("1.9"));
+
+        assertEquals(new BigDecimal("0.9"), BIGDECIMAL_ENGINE.toNumber(".9"));
+        assertEquals(0.9, CONSERVATIVE_ENGINE.toNumber(".9"));
+    }
+
 }
diff --git a/src/test/java/freemarker/core/NumberBiTest.java b/src/test/java/freemarker/core/NumberBiTest.java
new file mode 100644
index 0000000..3f3bd44
--- /dev/null
+++ b/src/test/java/freemarker/core/NumberBiTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.core;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.TemplateException;
+import freemarker.test.TemplateTest;
+
+public class NumberBiTest extends TemplateTest {
+    @Override
+    protected Configuration createConfiguration() throws Exception {
+        Configuration conf = super.createConfiguration();
+        conf.setIncompatibleImprovements(Configuration.VERSION_2_3_21);
+        return conf;
+    }
+
+    @Test
+    public void testSimple() throws TemplateException, IOException {
+        assertNumberBi("1", "1");
+        assertNumberBi("-1", "-1");
+        assertNumberBi("1.9000", "1.9");
+        assertNumberBi("19E-1", "1.9");
+        assertNumberBi("INF", "INF");
+        assertNumberBi("-Infinity", "-INF");
+        assertNumberBi("NaN", "NaN");
+    }
+
+    @Test
+    public void testPlusPrefix() throws TemplateException, IOException {
+        assertNumberBi("+1", "1");
+    }
+
+    private void assertThrowsNumberFormatException(String s) {
+        assertErrorContains("${'" + s + "'?number}", NonNumericalException.class, "\"" + s + "\"");
+    }
+
+    private final void assertNumberBi(String input, String output) throws TemplateException, IOException {
+        assertOutput("${'" + input + "'?number?c}", output);
+    }
+}
\ No newline at end of file