This commit is contained in:
Denis Molony 2017-03-08 20:18:59 +11:00
parent 65aa71254c
commit 6f9558674f
9 changed files with 89 additions and 71 deletions

View File

@ -20,8 +20,7 @@ public class VisicalcFile extends AbstractFile
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Visicalc : " + name + "\n"); text.append ("Visicalc : " + name + "\n\n");
text.append ("Cells : " + sheet.size () + "\n\n");
text.append (sheet.getTextDisplay (debug)); text.append (sheet.getTextDisplay (debug));
return text.toString (); return text.toString ();

View File

@ -20,13 +20,14 @@ public class Average extends Function
for (Address address : range) for (Address address : range)
{ {
Cell cell = parent.getCell (address); Cell cell = parent.getCell (address);
if (cell.isValueType (ValueType.NA)) if (cell.isValueType (ValueType.NA))
continue; continue;
if (!cell.isValueType (ValueType.VALUE)) if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = cell.getValueType ();
break; return;
} }
total += cell.getValue (); total += cell.getValue ();
@ -34,11 +35,12 @@ public class Average extends Function
} }
if (totalChecked == 0) if (totalChecked == 0)
valueType = ValueType.NA;
else
{ {
value = total / totalChecked; valueType = ValueType.ERROR;
valueType = ValueType.VALUE; return;
} }
value = total / totalChecked;
valueType = ValueType.VALUE;
} }
} }

View File

@ -132,10 +132,14 @@ class Cell extends AbstractValue implements Comparable<Cell>
// format cell value for output // format cell value for output
String getText (int colWidth, char globalFormat) String getText (int colWidth, char globalFormat)
{ {
char fmtChar = cellFormat != ' ' ? cellFormat : globalFormat;
switch (cellType) switch (cellType)
{ {
case LABEL: case LABEL:
return Format.justify (label, colWidth, cellFormat); if (fmtChar == ' ')
fmtChar = 'L';
return Format.justify (label, colWidth, fmtChar);
case REPEATING_CHARACTER: case REPEATING_CHARACTER:
return Format.justify (repeat, colWidth, ' '); return Format.justify (repeat, colWidth, ' ');
@ -146,29 +150,23 @@ class Cell extends AbstractValue implements Comparable<Cell>
case VALUE: case VALUE:
if (!isValueType (ValueType.VALUE)) if (!isValueType (ValueType.VALUE))
{ {
char fmt = if (fmtChar == ' ')
cellFormat != ' ' ? cellFormat : globalFormat != ' ' ? globalFormat : 'R'; fmtChar = 'R';
return Format.justify (value.getText (), colWidth, fmt); return " " + Format.justify (value.getText (), colWidth - 1, fmtChar);
} }
char formatChar = cellFormat != ' ' ? cellFormat : globalFormat; return " " + Format.format (value, fmtChar, colWidth - 1);
return " " + Format.format (value, formatChar, colWidth - 1);
default: default:
assert false; assert false;
return getText (); // not possible return "Impossible";
} }
} }
@Override @Override
public double getValue () public double getValue ()
{ {
// if (value == null) return cellType == CellType.VALUE ? value.getValue () : 0;
// calculate ();
if (cellType != CellType.VALUE)
return 0;
return value.getValue ();
} }
@Override @Override
@ -188,39 +186,20 @@ class Cell extends AbstractValue implements Comparable<Cell>
if (cellType == CellType.EMPTY) if (cellType == CellType.EMPTY)
return ""; return "";
assert cellType == CellType.VALUE;
return value.getText (); return value.getText ();
} }
@Override @Override
public boolean isValueType (ValueType type) public boolean isValueType (ValueType type)
{ {
// if (cellType == CellType.LABEL || cellType == CellType.REPEATING_CHARACTER)
// return type == ValueType.VALUE;
//
// if (cellType == CellType.EMPTY)
// return type == ValueType.NA;
//
// assert value != null : "bollocks " + address;
// return value.isValueType (type);
return type == getValueType (); return type == getValueType ();
} }
public boolean isCellType (CellType type)
{
return cellType == type;
}
@Override @Override
public void calculate () public void calculate ()
{ {
// if (value != null && value.isValueType (ValueType.VALUE)) if (cellType == CellType.VALUE)
// return;
//
// if (expressionText == null)
// expressionText = "";
// value = new Expression (parent, expressionText).reduce ();
if (value != null)
value.calculate (); value.calculate ();
} }

View File

@ -27,11 +27,10 @@ class Count extends Function
if (!cell.isValueType (ValueType.VALUE)) if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = cell.getValueType ();
break; return;
} }
if (cell.getValue () != 0.0) value++;
value++;
} }
} }
} }

View File

@ -194,7 +194,14 @@ class Expression extends AbstractValue implements Iterable<Value>
else if (operator.equals ("*")) else if (operator.equals ("*"))
value *= nextValue; value *= nextValue;
else if (operator.equals ("/")) else if (operator.equals ("/"))
{
if (nextValue == 0)
{
valueType = ValueType.ERROR;
return;
}
value /= nextValue; value /= nextValue;
}
else if (operator.equals ("^")) else if (operator.equals ("^"))
value = Math.pow (value, nextValue); value = Math.pow (value, nextValue);
} }

View File

@ -1,10 +1,8 @@
package com.bytezone.diskbrowser.visicalc; package com.bytezone.diskbrowser.visicalc;
import java.text.DecimalFormat;
public class Format public class Format
{ {
private static final DecimalFormat nf = new DecimalFormat ("#####0.00"); // private static final DecimalFormat nf = new DecimalFormat ("#####0.00");
private Format () private Format ()
{ {
@ -23,9 +21,10 @@ public class Format
case 'R': case 'R':
case ' ': case ' ':
// this could be improved // this could be improved
String numberFormat = String.format ("%%%d.5f", colWidth + 6); String numberFormat = String.format ("%%%d.7f", colWidth + 8);
String val = String.format (numberFormat, actualValue); String val = String.format (numberFormat, actualValue);
val = val.trim ();
while (val.endsWith ("0")) while (val.endsWith ("0"))
val = val.substring (0, val.length () - 1); val = val.substring (0, val.length () - 1);
if (val.endsWith (".")) if (val.endsWith ("."))
@ -33,15 +32,25 @@ public class Format
if (val.startsWith ("0.")) if (val.startsWith ("0."))
val = val.substring (1); val = val.substring (1);
if (val.length () > colWidth) if (val.length () > colWidth && val.indexOf ('.') >= 0)
val = val.substring (val.length () - colWidth); {
val = val.substring (0, colWidth);
}
// System.out.printf ("len:%d fmt: %s%n", val.length (), formatChar); // System.out.printf ("len:%d fmt: %s%n", val.length (), formatChar);
if (val.startsWith (" ") && formatChar == 'L') if (formatChar == 'L')
{ {
String leftFormat = String.format ("%%-%ds", colWidth); String leftFormat = String.format ("%%-%ds", colWidth);
val = String.format (leftFormat, val.trim ()); val = String.format (leftFormat, val);
} }
else
{
String rightFormat = String.format ("%%%ds", colWidth);
val = String.format (rightFormat, val);
}
if (val.length () > colWidth)
return ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>".substring (0, colWidth);
return val; return val;
@ -53,8 +62,15 @@ public class Format
return result; return result;
case '$': case '$':
String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth); String currencyFormat = String.format ("%%%d.%df", colWidth + 3, 2);
return String.format (currencyFormat, nf.format (actualValue)); result = String.format (currencyFormat, actualValue).trim ();
String rightFormat = String.format ("%%%ds", colWidth);
val = String.format (rightFormat, result);
// System.out.println (result);
// System.out.println (val);
if (result.length () > colWidth)
return ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>".substring (0, colWidth);
return val;
case '*': case '*':
String graphFormat = String.format ("%%-%d.%ds", colWidth, colWidth); String graphFormat = String.format ("%%-%d.%ds", colWidth, colWidth);

View File

@ -12,8 +12,10 @@ class Lookup extends Function
super (parent, text); super (parent, text);
int pos = text.indexOf (','); int pos = text.indexOf (',');
sourceText = text.substring (8, pos); sourceText = text.substring (8, pos);
source = new Expression (parent, sourceText); source = new Expression (parent, sourceText);
rangeText = text.substring (pos + 1, text.length () - 1); rangeText = text.substring (pos + 1, text.length () - 1);
range = new Range (parent, rangeText); range = new Range (parent, rangeText);
@ -43,7 +45,9 @@ class Lookup extends Function
for (Address address : range) for (Address address : range)
{ {
Cell cell = parent.getCell (address); Cell cell = parent.getCell (address);
if (cell != null && cell.getValue () > sourceValue) // past the value if (cell.isValueType (ValueType.NA))
continue;
if (cell.getValue () > sourceValue) // past the value
break; break;
target = address; target = address;
} }

View File

@ -2,23 +2,24 @@ package com.bytezone.diskbrowser.visicalc;
public class Npv extends Function public class Npv extends Function
{ {
// private final String valueText; private final String valueText;
// private final String rangeText; private final String rangeText;
//
// private final Expression valueExp; private final Expression rateExp;
private final Range range; private final Range range;
Npv (Sheet parent, String text) Npv (Sheet parent, String text)
{ {
super (parent, text); super (parent, text);
range = new Range (parent, text); int pos = text.indexOf (',');
valueText = text.substring (5, pos);
rangeText = text.substring (pos + 1, text.length () - 1);
// int pos = text.indexOf (','); rateExp = new Expression (parent, valueText);
// valueText = text.substring (8, pos); range = new Range (parent, rangeText);
// rangeText = text.substring (pos + 1, text.length () - 1);
// values.add (rateExp);
// valueExp = new Expression (parent, valueText);
} }
@Override @Override
@ -27,8 +28,20 @@ public class Npv extends Function
value = 0; value = 0;
valueType = ValueType.VALUE; valueType = ValueType.VALUE;
rateExp.calculate ();
if (!rateExp.isValueType (ValueType.VALUE))
{
valueType = rateExp.getValueType ();
return;
}
double rate = 1 + rateExp.getValue ();
int period = 0;
for (Address address : range) for (Address address : range)
{ {
++period;
Cell cell = parent.getCell (address); Cell cell = parent.getCell (address);
if (cell.isValueType (ValueType.NA)) if (cell.isValueType (ValueType.NA))
continue; continue;
@ -36,10 +49,10 @@ public class Npv extends Function
if (!cell.isValueType (ValueType.VALUE)) if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = cell.getValueType ();
break; return;
} }
double temp = cell.getValue (); value += cell.getValue () / Math.pow (rate, period);
} }
} }
} }

View File

@ -8,7 +8,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.visicalc.Cell.CellType;
public class Sheet public class Sheet
{ {
@ -177,8 +176,7 @@ public class Sheet
{ {
Map<Integer, Cell> cells = order == 'R' ? rowOrderCells : columnOrderCells; Map<Integer, Cell> cells = order == 'R' ? rowOrderCells : columnOrderCells;
for (Cell cell : cells.values ()) for (Cell cell : cells.values ())
if (cell.isCellType (CellType.VALUE)) cell.calculate ();
cell.calculate ();
} }
private int getLineLength (byte[] buffer, int offset) private int getLineLength (byte[] buffer, int offset)
@ -371,8 +369,9 @@ public class Sheet
recalculationOrder == 'R' ? "Row" : "Column")); recalculationOrder == 'R' ? "Row" : "Column"));
text.append (String.format ("Recalculation : %s%n", text.append (String.format ("Recalculation : %s%n",
recalculation == 'A' ? "Automatic" : "Manual")); recalculation == 'A' ? "Automatic" : "Manual"));
text.append (String.format ("Cells : %d%n", size ()));
if (rowOrderCells.size () > 0) if (size () > 0)
text.append (String.format ("Range : %s:%s%n%n", text.append (String.format ("Range : %s:%s%n%n",
Address.getCellName (minRow + 1, minColumn), Address.getCellName (minRow + 1, minColumn),
Address.getCellName (maxRow + 1, maxColumn))); Address.getCellName (maxRow + 1, maxColumn)));