diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java index acc9e72..f126815 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java @@ -118,40 +118,46 @@ final public class FourCornerRecipe { } static public List embedNCR1632Denominator(BigInteger value) { - return embedNCR1632Value(value, FourCornerDotCake.FC_NCR1632_XD.getStart()); + return embedNCR1632Value(new ArrayList<>(), value, FourCornerDotCake.FC_NCR1632_XD.getStart()); } static public List embedNCR1632Numerator(BigInteger value) { - return embedNCR1632Value(value, FourCornerDotCake.FC_NCR1632_XN.getStart()); + return embedNCR1632Value(new ArrayList<>(), value, FourCornerDotCake.FC_NCR1632_XN.getStart()); } - static private List embedNCR1632Value(BigInteger value, int bankStart) { + static public void embedNCR1632Denominator(List result, BigInteger value) { + embedNCR1632Value(result, value, FourCornerDotCake.FC_NCR1632_XD.getStart()); + } + + static public void embedNCR1632Numerator(List result, BigInteger value) { + embedNCR1632Value(result, value, FourCornerDotCake.FC_NCR1632_XN.getStart()); + } + + static final private BigInteger NCR1632_MASK_PAGE = BigInteger.valueOf(0x1FF); + static final private BigInteger NCR1632_MASK_MAX = new BigInteger("FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF", 16); + + static private List embedNCR1632Value(List result, BigInteger value, int bankStart) { if (value.equals(BigInteger.ZERO)) { throw new IllegalArgumentException("The value ZERO is not allowed."); } //if (value.signum() == -1) { // // TODO: check if we need one octal for pos/neg/qNaN/sNaN/pos_inf/neg_inf/free/free options //} - List result = new ArrayList<>(); + if (value.and(NCR1632_MASK_MAX).equals(BigInteger.ZERO)) { + throw new IllegalArgumentException("Value is larger than 576 bit: " + value); + } BigInteger valueZero = value.subtract(BigInteger.ONE); if (valueZero.equals(BigInteger.ZERO)) { result.add(bankStart); return result; } - BigInteger pageSize = BigInteger.valueOf(0x1FF); - BigInteger reminder = valueZero; - for (int i = 63; i >= 0; i--) { - int bankValue = valueZero.shiftRight(i * 9).and(pageSize).intValue(); + int bankValue = valueZero.shiftRight(i * 9).and(NCR1632_MASK_PAGE).intValue(); if (bankValue == 0) { continue; } int cakePoint = bankStart + bankValue + (i * 512); - result.add(cakePoint); - reminder = reminder.subtract(BigInteger.valueOf(bankValue).shiftLeft(i * 9)); - } - if (!reminder.equals(BigInteger.ZERO)) { - throw new IllegalArgumentException("Value is larger than 576 bit: " + reminder + " of " + value); + result.add(cakePoint); } return result; } diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java index b54b8b1..fee52d1 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java @@ -64,8 +64,8 @@ public class FourCornerZionStenoGrapher { @Override public void strobeNCR1632(BigInteger denominator, BigInteger numerator) { - out.addAll(FourCornerRecipe.embedNCR1632Denominator(denominator)); - out.addAll(FourCornerRecipe.embedNCR1632Numerator(numerator)); + FourCornerRecipe.embedNCR1632Denominator(out, denominator); + FourCornerRecipe.embedNCR1632Numerator(out, numerator); } @Override diff --git a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java new file mode 100644 index 0000000..4431555 --- /dev/null +++ b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2004-2014, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.fc18; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Tests FourCornerRecipe methods. + * + * @author Willem Cazander + * @version 1.0 Aug 7, 2025 + */ +public class FourCornerRecipeTest { + + @Test + public void testNCRCount1024() throws Exception { + List cdc = new ArrayList<>(); + for (int x = 1; x <= 1024; x++) { + BigInteger v = BigInteger.valueOf(x); + cdc.addAll(FourCornerRecipe.embedNCR1632Denominator(v)); + + //cdc.add(FourCornerDotCake.FC_NCR1632_XN.getStart()); // NXX_1 + List nomList = FourCornerRecipe.embedNCR1632Numerator(BigInteger.ONE); + Assertions.assertEquals(1, nomList.size()); + cdc.addAll(nomList); // NXX_1 + } + String res = FourCornerUnicodeDisplay.text().renderFromInt18(cdc); + Assertions.assertTrue(res.startsWith("¹/₁¹/₂"), "missing " + res); + Assertions.assertTrue(res.endsWith("¹/₁₀₂₃¹/₁₀₂₄"), "missing " + res); + } + + @Test + public void testNCRMaxValue() throws Exception { + BigInteger maxValue = new BigInteger("FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF", 16); + FourCornerRecipe.embedNCR1632Numerator(maxValue); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + FourCornerRecipe.embedNCR1632Numerator(maxValue.add(BigInteger.ONE)); + }); + } +} diff --git a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/LexerNCRTest.java b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/LexerNCRTest.java index a889604..ef9f057 100644 --- a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/LexerNCRTest.java +++ b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/LexerNCRTest.java @@ -133,21 +133,4 @@ public class LexerNCRTest { String resSuber = "₂₄₇₃₃₀₄₀₁₄₇₃₁₀₄₅₃₄₀₆₀₅₀₂₅₂₁₀₁₉₆₄₇₁₉₀₀₃₅₁₃₁₃₄₉₁₀₁₂₁₁₈₃₉₉₁₄₀₆₃₀₅₆₀₉₂₈₉₇₂₂₅₁₀₆₅₃₁₈₆₇₁₇₀₃₁₆₄₀₁₀₆₁₂₄₃₀₄₄₉₈₉₅₉₇₆₇₁₄₂₆₀₁₆₁₃₉₃₃₉₃₅₁₃₆₅₀₃₄₃₀₆₇₅₁₂₀₉₉₆₇₅₄₆₁₅₅₁₀₁₈₉₃₁₆₇₉₁₆₆₀₆₇₇₂₁₄₈₆₉₉₁₃₆"; Assertions.assertEquals(resSuper + "/" + resSuber, FourCornerUnicodeDisplay.text().renderFromInt18(cdc)); } - - @Test - public void testNCRCount1024() throws Exception { - List cdc = new ArrayList<>(); - for (int x = 1; x <= 1024; x++) { - BigInteger v = BigInteger.valueOf(x); - cdc.addAll(FourCornerRecipe.embedNCR1632Denominator(v)); - - //cdc.add(FourCornerDotCake.FC_NCR1632_XN.getStart()); // NXX_1 - List nomList = FourCornerRecipe.embedNCR1632Numerator(BigInteger.ONE); - Assertions.assertEquals(1, nomList.size()); - cdc.addAll(nomList); // NXX_1 - } - String res = FourCornerUnicodeDisplay.text().renderFromInt18(cdc); - Assertions.assertTrue(res.startsWith("¹/₁¹/₂"), "missing " + res); - Assertions.assertTrue(res.endsWith("¹/₁₀₂₃¹/₁₀₂₄"), "missing " + res); - } }