mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-06-19 14:29:39 +00:00
NPV
This commit is contained in:
parent
65aa71254c
commit
6f9558674f
|
@ -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 ();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user