summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Hentenaar <tim@hentenaar.com>2014-03-22 02:47:33 +0100
committerTim Hentenaar <tim@hentenaar.com>2019-02-18 03:48:17 +0100
commitc4f1bdb16b560d813e6ded83c2d7a4f4d280a90a (patch)
tree4c66bd8d991bb57ddc7c0ea94dc51248dcdc4efe
parentbe5114cebfdc29788cf038d349c0ed6cce4bb536 (diff)
Add bitwise ops and base conversion (DEC/OCT/HEX) in TI mode
These operations implicitly truncate their parameters, and result to integers: * not * and * or * xor * shl * shr * mod * trunc Base 2 was left out of the base conversion code intentionally as it would require making the UI at least one third wider. Attempts to change base with negative values will simply display "error." Note that with larger numbers, the result may be inaccurate due to rounding. I've also bound the Return key to the equal() action. Signed-off-by: Tim Hentenaar <tim@hentenaar.com>
-rw-r--r--actions.c98
-rw-r--r--app-defaults/XCalc200
-rw-r--r--math.c185
-rw-r--r--xcalc.c19
-rw-r--r--xcalc.h19
5 files changed, 426 insertions, 95 deletions
diff --git a/actions.c b/actions.c
index 50bf7b4..2857f96 100644
--- a/actions.c
+++ b/actions.c
@@ -46,7 +46,9 @@ from the X Consortium.
#endif
static void add(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void and(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void back(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void base(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void bell(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void clearit(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void cosine(Widget w, XEvent *ev, String *vector, Cardinal *count);
@@ -63,11 +65,14 @@ static void factorial(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void inverse(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void leftParen(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void logarithm(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void mod(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void multiply(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void naturalLog(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void negate(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void nop(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void not(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void off(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void or(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void pi(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void power(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void quit(Widget w, XEvent *ev, String *vector, Cardinal *count);
@@ -77,6 +82,8 @@ static void rightParen(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void roll(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void scientific(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void selection(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void shl(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void shr(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void sine(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void square(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void squareRoot(Widget w, XEvent *ev, String *vector, Cardinal *count);
@@ -85,6 +92,8 @@ static void subtract(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void sum(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void tangent(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void tenpower(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void xtrunc(Widget w, XEvent *ev, String *vector, Cardinal *count);
+static void xor(Widget w, XEvent *ev, String *vector, Cardinal *count);
static void XexchangeY(Widget w, XEvent *ev, String *vector, Cardinal *count);
/*
@@ -93,7 +102,9 @@ static void XexchangeY(Widget w, XEvent *ev, String *vector, Cardinal *count);
XtActionsRec Actions[] = {
{"add", add}, /* addition */
+{"and", and}, /* bitwise and */
{"back", back}, /* HP-specific backspace */
+{"base", base}, /* base conversion */
{"bell", bell}, /* ring bell */
{"clear", clearit}, /* TI-specific clear calculator state */
{"cosine", cosine}, /* trigonometric function cosine */
@@ -110,11 +121,14 @@ XtActionsRec Actions[] = {
{"inverse", inverse}, /* inverse */
{"leftParen", leftParen}, /* TI-specific left parenthesis */
{"logarithm", logarithm}, /* logarithm base 10 */
+{"mod", mod}, /* modulus */
{"multiply", multiply}, /* multiplication */
{"naturalLog", naturalLog}, /* natural logarithm base e */
{"negate", negate}, /* change sign */
{"nop", nop}, /* no operation, rings bell */
+{"not", not}, /* bitwise not */
{"off", off}, /* clear state */
+{"or", or}, /* bitwise or */
{"pi", pi}, /* the number pi */
{"power", power}, /* raise to an arbitrary power */
{"quit", quit}, /* quit */
@@ -124,6 +138,8 @@ XtActionsRec Actions[] = {
{"roll", roll}, /* HP-specific roll stack */
{"scientific", scientific}, /* scientfic notation (EE) */
{"selection", selection}, /* copy selection */
+{"shl", shl}, /* arithmetic shift left */
+{"shr", shr}, /* arithmetic shift right */
{"sine", sine}, /* trigonometric function sine */
{"square", square}, /* square */
{"squareRoot", squareRoot}, /* square root */
@@ -132,6 +148,8 @@ XtActionsRec Actions[] = {
{"sum", sum}, /* memory summation */
{"tangent", tangent}, /* trigonometric function tangent */
{"tenpower", tenpower}, /* 10 raised to to an arbitrary power */
+{"trunc", xtrunc}, /* truncate to integer */
+{"xor", xor}, /* bitwise xor */
{"XexchangeY", XexchangeY} /* HP-specific exchange X and Y registers */
};
@@ -146,6 +164,14 @@ static void add(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void and(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kAND);
+ rpn ? twof(kAND) : twoop(kAND);
+ post_op();
+}
+
+/*ARGSUSED*/
static void back(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kBKSP);
@@ -154,6 +180,14 @@ static void back(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void base(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kBASE);
+ change_base();
+ post_op();
+}
+
+/*ARGSUSED*/
static void bell(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
ringbell();
@@ -196,6 +230,7 @@ static void digit(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
switch (vector[0][0])
{
+ case '0': XCALC_PRE_OP(kZERO); numeric(kZERO); break;
case '1': XCALC_PRE_OP(kONE); numeric(kONE); break;
case '2': XCALC_PRE_OP(kTWO); numeric(kTWO); break;
case '3': XCALC_PRE_OP(kTHREE); numeric(kTHREE); break;
@@ -205,7 +240,12 @@ static void digit(Widget w, XEvent *ev, String *vector, Cardinal *count)
case '7': XCALC_PRE_OP(kSEVEN); numeric(kSEVEN); break;
case '8': XCALC_PRE_OP(kEIGHT); numeric(kEIGHT); break;
case '9': XCALC_PRE_OP(kNINE); numeric(kNINE); break;
- case '0': XCALC_PRE_OP(kZERO); numeric(kZERO); break;
+ case 'A': XCALC_PRE_OP(kxA); numeric(kxA); break;
+ case 'B': XCALC_PRE_OP(kxB); numeric(kxB); break;
+ case 'C': XCALC_PRE_OP(kxC); numeric(kxC); break;
+ case 'D': XCALC_PRE_OP(kxD); numeric(kxD); break;
+ case 'E': XCALC_PRE_OP(kxE); numeric(kxE); break;
+ case 'F': XCALC_PRE_OP(kxF); numeric(kxF); break;
}
post_op();
}
@@ -291,6 +331,14 @@ static void logarithm(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void mod(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kMOD);
+ rpn ? twof(kMOD) : twoop(kMOD);
+ post_op();
+}
+
+/*ARGSUSED*/
static void multiply(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kMUL);
@@ -321,6 +369,14 @@ static void nop(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void not(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kNOT);
+ oneop(kNOT);
+ post_op();
+}
+
+/*ARGSUSED*/
static void off(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kOFF);
@@ -329,6 +385,14 @@ static void off(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void or(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kOR);
+ rpn ? twof(kOR) : twoop(kOR);
+ post_op();
+}
+
+/*ARGSUSED*/
static void pi(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kPI);
@@ -400,6 +464,22 @@ static void selection(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void shl(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kSHL);
+ rpn ? twof(kSHL) : twoop(kSHL);
+ post_op();
+}
+
+/*ARGSUSED*/
+static void shr(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kSHR);
+ rpn ? twof(kSHR) : twoop(kSHR);
+ post_op();
+}
+
+/*ARGSUSED*/
static void sine(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kSIN);
@@ -464,6 +544,22 @@ static void tenpower(Widget w, XEvent *ev, String *vector, Cardinal *count)
}
/*ARGSUSED*/
+static void xtrunc(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kTRUNC);
+ oneop(kTRUNC);
+ post_op();
+}
+
+/*ARGSUSED*/
+static void xor(Widget w, XEvent *ev, String *vector, Cardinal *count)
+{
+ XCALC_PRE_OP(kXOR);
+ rpn ? twof(kXOR) : twoop(kXOR);
+ post_op();
+}
+
+/*ARGSUSED*/
static void XexchangeY(Widget w, XEvent *ev, String *vector, Cardinal *count)
{
XCALC_PRE_OP(kXXY);
diff --git a/app-defaults/XCalc b/app-defaults/XCalc
index 540df58..fa3684c 100644
--- a/app-defaults/XCalc
+++ b/app-defaults/XCalc
@@ -42,6 +42,15 @@ XCalc*bevel.screen.P.label: ()
XCalc*bevel.screen.P.fromHoriz: GRAD
XCalc*bevel.screen.P.fromVert: LCD
XCalc*bevel.screen.P.horizDistance: 2
+XCalc*bevel.screen.HEX.fromHoriz: P
+XCalc*bevel.screen.HEX.fromVert: LCD
+XCalc*bevel.screen.HEX.horizDistance: 1
+XCalc*bevel.screen.DEC.fromHoriz: P
+XCalc*bevel.screen.DEC.fromVert: LCD
+XCalc*bevel.screen.DEC.horizDistance: 1
+XCalc*bevel.screen.OCT.fromHoriz: P
+XCalc*bevel.screen.OCT.fromVert: LCD
+XCalc*bevel.screen.OCT.horizDistance: 1
!XCalc*ti.Geometry: 171x252
XCalc*ti.bevel.screen.LCD.width: 186
@@ -59,6 +68,12 @@ XCalc*ti.bevel.screen.LCD.translations: #replace\n\
None<Key>7:digit(7)\n\
None<Key>8:digit(8)\n\
None<Key>9:digit(9)\n\
+ Shift<Key>a:digit(A)\n\
+ Shift<Key>b:digit(B)\n\
+ Shift<Key>c:digit(C)\n\
+ Shift<Key>d:digit(D)\n\
+ Shift<Key>e:digit(E)\n\
+ Shift<Key>f:digit(F)\n\
<Key>KP_0:digit(0)\n\
<Key>KP_1:digit(1)\n\
<Key>KP_2:digit(2)\n\
@@ -71,6 +86,7 @@ XCalc*ti.bevel.screen.LCD.translations: #replace\n\
<Key>KP_9:digit(9)\n\
<Key>KP_Enter:equal()\n\
<Key>KP_Equal:equal()\n\
+ <Key>Return:equal()\n\
<Key>KP_Multiply:multiply()\n\
<Key>KP_Add:add()\n\
<Key>KP_Subtract:subtract()\n\
@@ -87,6 +103,13 @@ XCalc*ti.bevel.screen.LCD.translations: #replace\n\
:<Key>(:leftParen()\n\
:<Key>):rightParen()\n\
:<Key>!:factorial()\n\
+ :<Key>|:or()\n\
+ :<Key>&:and()\n\
+ :<Key><:shl()\n\
+ :<Key>>:shr()\n\
+ :<Key>~:not()\n\
+ :<Key>%:mod()\n\
+ <Key>x:xor()\n\
<Key>e:e()\n\
:<Key>^:power()\n\
<Key>p:pi()\n\
@@ -140,62 +163,95 @@ XCalc*ti.button14.translations: #override<Btn1Down>,<Btn1Up>:naturalLog()unset()
XCalc*ti.button15.label: y^x
XCalc*ti.button15.translations: #override<Btn1Down>,<Btn1Up>:power()unset()
-XCalc*ti.button16.font: -adobe-symbol-*-*-*-*-*-120-*-*-*-*-*-*
-XCalc*ti.button16.label: \160
-XCalc*ti.button16.translations: #override<Btn1Down>,<Btn1Up>:pi()unset()
-XCalc*ti.button17.label: x!
-XCalc*ti.button17.translations: #override<Btn1Down>,<Btn1Up>:factorial()unset()
-XCalc*ti.button18.label: (
-XCalc*ti.button18.translations: #override<Btn1Down>,<Btn1Up>:leftParen()unset()
-XCalc*ti.button19.label: )
-XCalc*ti.button19.translations: #override<Btn1Down>,<Btn1Up>:rightParen()unset()
-XCalc*ti.button20.font: -adobe-symbol-*-*-*-*-*-120-*-*-*-*-*-*
-XCalc*ti.button20.label: \270
-XCalc*ti.button20.translations: #override<Btn1Down>,<Btn1Up>:divide()unset()
-
-XCalc*ti.button21.label: STO
-XCalc*ti.button21.translations: #override<Btn1Down>,<Btn1Up>:store()unset()
-XCalc*ti.button22.label: 7
-XCalc*ti.button22.translations: #override<Btn1Down>,<Btn1Up>:digit(7)unset()
-XCalc*ti.button23.label: 8
-XCalc*ti.button23.translations: #override<Btn1Down>,<Btn1Up>:digit(8)unset()
-XCalc*ti.button24.label: 9
-XCalc*ti.button24.translations: #override<Btn1Down>,<Btn1Up>:digit(9)unset()
-XCalc*ti.button25.label: *
-XCalc*ti.button25.translations: #override<Btn1Down>,<Btn1Up>:multiply()unset()
-
-XCalc*ti.button26.label: RCL
-XCalc*ti.button26.translations: #override<Btn1Down>,<Btn1Up>:recall()unset()
-XCalc*ti.button27.label: 4
-XCalc*ti.button27.translations: #override<Btn1Down>,<Btn1Up>:digit(4)unset()
-XCalc*ti.button28.label: 5
-XCalc*ti.button28.translations: #override<Btn1Down>,<Btn1Up>:digit(5)unset()
-XCalc*ti.button29.label: 6
-XCalc*ti.button29.translations: #override<Btn1Down>,<Btn1Up>:digit(6)unset()
-XCalc*ti.button30.label: -
-XCalc*ti.button30.translations: #override<Btn1Down>,<Btn1Up>:subtract()unset()
-
-XCalc*ti.button31.label: SUM
-XCalc*ti.button31.translations: #override<Btn1Down>,<Btn1Up>:sum()unset()
-XCalc*ti.button32.label: 1
-XCalc*ti.button32.translations: #override<Btn1Down>,<Btn1Up>:digit(1)unset()
-XCalc*ti.button33.label: 2
-XCalc*ti.button33.translations: #override<Btn1Down>,<Btn1Up>:digit(2)unset()
-XCalc*ti.button34.label: 3
-XCalc*ti.button34.translations: #override<Btn1Down>,<Btn1Up>:digit(3)unset()
-XCalc*ti.button35.label: +
-XCalc*ti.button35.translations: #override<Btn1Down>,<Btn1Up>:add()unset()
-
-XCalc*ti.button36.label: EXC
-XCalc*ti.button36.translations: #override<Btn1Down>,<Btn1Up>:exchange()unset()
-XCalc*ti.button37.label: 0
-XCalc*ti.button37.translations: #override<Btn1Down>,<Btn1Up>:digit(0)unset()
-XCalc*ti.button38.label: .
-XCalc*ti.button38.translations: #override<Btn1Down>,<Btn1Up>:decimal()unset()
-XCalc*ti.button39.label: +/-
-XCalc*ti.button39.translations: #override<Btn1Down>,<Btn1Up>:negate()unset()
-XCalc*ti.button40.label: =
-XCalc*ti.button40.translations: #override<Btn1Down>,<Btn1Up>:equal()unset()
+XCalc*ti.button16.label: not
+XCalc*ti.button16.translations: #override<Btn1Down>,<Btn1Up>:not()unset()
+XCalc*ti.button17.label: and
+XCalc*ti.button17.translations: #override<Btn1Down>,<Btn1Up>:and()unset()
+XCalc*ti.button18.label: or
+XCalc*ti.button18.translations: #override<Btn1Down>,<Btn1Up>:or()unset()
+XCalc*ti.button19.label: xor
+XCalc*ti.button19.translations: #override<Btn1Down>,<Btn1Up>:xor()unset()
+XCalc*ti.button20.label: trunc
+XCalc*ti.button20.translations: #override<Btn1Down>,<Btn1Up>:trunc()unset()
+
+XCalc*ti.button21.font: -adobe-symbol-*-*-*-*-*-120-*-*-*-*-*-*
+XCalc*ti.button21.label: \160
+XCalc*ti.button21.translations: #override<Btn1Down>,<Btn1Up>:pi()unset()
+XCalc*ti.button22.label: x!
+XCalc*ti.button22.translations: #override<Btn1Down>,<Btn1Up>:factorial()unset()
+XCalc*ti.button23.label: (
+XCalc*ti.button23.translations: #override<Btn1Down>,<Btn1Up>:leftParen()unset()
+XCalc*ti.button24.label: )
+XCalc*ti.button24.translations: #override<Btn1Down>,<Btn1Up>:rightParen()unset()
+XCalc*ti.button25.label: base
+XCalc*ti.button25.translations: #override<Btn1Down>,<Btn1Up>:base()unset()
+
+XCalc*ti.button26.label: shl
+XCalc*ti.button26.translations: #override<Btn1Down>,<Btn1Up>:shl()unset()
+XCalc*ti.button27.label: D
+XCalc*ti.button27.translations: #override<Btn1Down>,<Btn1Up>:digit(D)unset()
+XCalc*ti.button28.label: E
+XCalc*ti.button28.translations: #override<Btn1Down>,<Btn1Up>:digit(E)unset()
+XCalc*ti.button29.label: F
+XCalc*ti.button29.translations: #override<Btn1Down>,<Btn1Up>:digit(F)unset()
+XCalc*ti.button30.label: shr
+XCalc*ti.button30.translations: #override<Btn1Down>,<Btn1Up>:shr()unset()
+
+XCalc*ti.button31.label: mod
+XCalc*ti.button31.translations: #override<Btn1Down>,<Btn1Up>:mod()unset()
+XCalc*ti.button32.label: A
+XCalc*ti.button32.translations: #override<Btn1Down>,<Btn1Up>:digit(A)unset()
+XCalc*ti.button33.label: B
+XCalc*ti.button33.translations: #override<Btn1Down>,<Btn1Up>:digit(B)unset()
+XCalc*ti.button34.label: C
+XCalc*ti.button34.translations: #override<Btn1Down>,<Btn1Up>:digit(C)unset()
+XCalc*ti.button35.font: -adobe-symbol-*-*-*-*-*-120-*-*-*-*-*-*
+XCalc*ti.button35.label: \270
+XCalc*ti.button35.translations: #override<Btn1Down>,<Btn1Up>:divide()unset()
+
+XCalc*ti.button36.label: STO
+XCalc*ti.button36.translations: #override<Btn1Down>,<Btn1Up>:store()unset()
+XCalc*ti.button37.label: 7
+XCalc*ti.button37.translations: #override<Btn1Down>,<Btn1Up>:digit(7)unset()
+XCalc*ti.button38.label: 8
+XCalc*ti.button38.translations: #override<Btn1Down>,<Btn1Up>:digit(8)unset()
+XCalc*ti.button39.label: 9
+XCalc*ti.button39.translations: #override<Btn1Down>,<Btn1Up>:digit(9)unset()
+XCalc*ti.button40.label: *
+XCalc*ti.button40.translations: #override<Btn1Down>,<Btn1Up>:multiply()unset()
+
+XCalc*ti.button41.label: RCL
+XCalc*ti.button41.translations: #override<Btn1Down>,<Btn1Up>:recall()unset()
+XCalc*ti.button42.label: 4
+XCalc*ti.button42.translations: #override<Btn1Down>,<Btn1Up>:digit(4)unset()
+XCalc*ti.button43.label: 5
+XCalc*ti.button43.translations: #override<Btn1Down>,<Btn1Up>:digit(5)unset()
+XCalc*ti.button44.label: 6
+XCalc*ti.button44.translations: #override<Btn1Down>,<Btn1Up>:digit(6)unset()
+XCalc*ti.button45.label: -
+XCalc*ti.button45.translations: #override<Btn1Down>,<Btn1Up>:subtract()unset()
+
+XCalc*ti.button46.label: SUM
+XCalc*ti.button46.translations: #override<Btn1Down>,<Btn1Up>:sum()unset()
+XCalc*ti.button47.label: 1
+XCalc*ti.button47.translations: #override<Btn1Down>,<Btn1Up>:digit(1)unset()
+XCalc*ti.button48.label: 2
+XCalc*ti.button48.translations: #override<Btn1Down>,<Btn1Up>:digit(2)unset()
+XCalc*ti.button49.label: 3
+XCalc*ti.button49.translations: #override<Btn1Down>,<Btn1Up>:digit(3)unset()
+XCalc*ti.button50.label: +
+XCalc*ti.button50.translations: #override<Btn1Down>,<Btn1Up>:add()unset()
+
+XCalc*ti.button51.label: EXC
+XCalc*ti.button51.translations: #override<Btn1Down>,<Btn1Up>:exchange()unset()
+XCalc*ti.button52.label: 0
+XCalc*ti.button52.translations: #override<Btn1Down>,<Btn1Up>:digit(0)unset()
+XCalc*ti.button53.label: .
+XCalc*ti.button53.translations: #override<Btn1Down>,<Btn1Up>:decimal()unset()
+XCalc*ti.button54.label: +/-
+XCalc*ti.button54.translations: #override<Btn1Down>,<Btn1Up>:negate()unset()
+XCalc*ti.button55.label: =
+XCalc*ti.button55.translations: #override<Btn1Down>,<Btn1Up>:equal()unset()
XCalc*ti.button1.horizDistance: 4
XCalc*ti.button1.vertDistance: 12
@@ -290,6 +346,38 @@ XCalc*ti.button39.fromVert: button34
XCalc*ti.button40.fromHoriz: button39
XCalc*ti.button40.fromVert: button35
+XCalc*ti.button41.horizDistance: 4
+XCalc*ti.button41.fromVert: button36
+XCalc*ti.button42.fromHoriz: button41
+XCalc*ti.button42.fromVert: button37
+XCalc*ti.button43.fromHoriz: button42
+XCalc*ti.button43.fromVert: button38
+XCalc*ti.button44.fromHoriz: button43
+XCalc*ti.button44.fromVert: button39
+XCalc*ti.button45.fromHoriz: button44
+XCalc*ti.button45.fromVert: button40
+
+XCalc*ti.button46.horizDistance: 4
+XCalc*ti.button46.fromVert: button41
+XCalc*ti.button47.fromHoriz: button46
+XCalc*ti.button47.fromVert: button42
+XCalc*ti.button48.fromHoriz: button47
+XCalc*ti.button48.fromVert: button43
+XCalc*ti.button49.fromHoriz: button48
+XCalc*ti.button49.fromVert: button44
+XCalc*ti.button50.fromHoriz: button49
+XCalc*ti.button50.fromVert: button45
+
+XCalc*ti.button51.horizDistance: 4
+XCalc*ti.button51.fromVert: button46
+XCalc*ti.button52.fromHoriz: button51
+XCalc*ti.button52.fromVert: button47
+XCalc*ti.button53.fromHoriz: button52
+XCalc*ti.button53.fromVert: button48
+XCalc*ti.button54.fromHoriz: button53
+XCalc*ti.button54.fromVert: button49
+XCalc*ti.button55.fromHoriz: button54
+XCalc*ti.button55.fromVert: button50
!XCalc*hp.Geometry: 336x164
XCalc*hp.bevel.screen.LCD.width: 186
diff --git a/math.c b/math.c
index ff2db17..6e46692 100644
--- a/math.c
+++ b/math.c
@@ -43,7 +43,7 @@ jmp_buf env;
* functions. Much of it is shared between the infix and rpn modes.
*/
-static int flagINV, flagPAREN, flagM, drgmode; /* display flags */
+static int flagINV, flagPAREN, flagM, drgmode, numbase; /* display flags */
static double drg2rad=M_PI/180.0; /* Conversion factors for trig funcs */
static double rad2drg=180.0/M_PI;
@@ -94,17 +94,47 @@ strlcpy(char *dst, const char *src, size_t size)
* is non-zero then an error has occurred. On some systems (e.g. Ultrix),
* sscanf will call lower level routines that will set errno.
*/
-
static void
-parse_double (const char *src, const char *fmt, double *dp)
+parse_double(double *dp)
{
+ unsigned long n = 0;
int olderrno = errno;
- (void) sscanf (src, fmt, dp);
+ switch (numbase) {
+ case 8:
+ (void)sscanf(dispstr, "%lo", &n);
+ *dp = (double)n;
+ break;
+ case 16:
+ (void)sscanf(dispstr, "%lX", &n);
+ *dp = (double)n;
+ break;
+ default:
+ (void)sscanf(dispstr, "%lf", dp);
+ }
+
errno = olderrno;
return;
}
+/**
+ * Format the given double according to the
+ * selected number base.
+ */
+static void
+format_double(double n)
+{
+ switch (numbase) {
+ case 8:
+ snprintf(dispstr, sizeof(dispstr), "%lo", (long)n);
+ break;
+ case 16:
+ snprintf(dispstr, sizeof(dispstr), "%lX", (long)n);
+ break;
+ default:
+ snprintf(dispstr, sizeof(dispstr), "%.8g", n);
+ }
+}
/*********************************/
int pre_op(int keynum)
@@ -181,12 +211,13 @@ void post_op(void)
}
#endif
}
+
/*-------------------------------------------------------------------------*/
static void
DrawDisplay(void)
{
- if (strlen(dispstr) > 12) { /* strip out some decimal digits */
- char *estr = strchr(dispstr,'e'); /* search for exponent part */
+ if (strlen(dispstr) >= MAXDISP) { /* strip out some decimal digits */
+ char *estr = index(dispstr,'e'); /* search for exponent part */
if (!estr) dispstr[12]='\0'; /* no exp, just trunc. */
else {
char tmp[32];
@@ -204,6 +235,28 @@ DrawDisplay(void)
setflag(XCalc_RADIAN, (drgmode==RAD));
setflag(XCalc_GRADAM, (drgmode==GRAD));
setflag(XCalc_PAREN, (flagPAREN));
+ setflag(XCalc_HEX, (numbase==16));
+ setflag(XCalc_DEC, (numbase==10));
+ setflag(XCalc_OCT, (numbase==8));
+}
+
+/*-------------------------------------------------------------------------*/
+void
+change_base(void)
+{
+ parse_double(&dnum);
+
+ if (dnum >= 0) {
+ switch (numbase) {
+ case 8: numbase = 10; break;
+ case 10: numbase = 16; break;
+ case 16: numbase = 8; break;
+ }
+
+ format_double(dnum);
+ } else strlcpy(dispstr, "error", sizeof(dispstr));
+
+ DrawDisplay();
}
/*-------------------------------------------------------------------------*/
@@ -239,7 +292,7 @@ numeric(int keynum)
case kRCL:
PushNum(dnum);
dnum = mem[cell];
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
lift_enabled = 1;
entered = 1;
clrdisp++;
@@ -268,7 +321,9 @@ numeric(int keynum)
if ((int) strlen(dispstr) >= MAXDISP)
return;
+ st[0] = '\0';
switch (keynum){
+ case kZERO: st[0] = '0'; break;
case kONE: st[0] = '1'; break;
case kTWO: st[0] = '2'; break;
case kTHREE: st[0] = '3'; break;
@@ -276,12 +331,20 @@ numeric(int keynum)
case kFIVE: st[0] = '5'; break;
case kSIX: st[0] = '6'; break;
case kSEVEN: st[0] = '7'; break;
- case kEIGHT: st[0] = '8'; break;
- case kNINE: st[0] = '9'; break;
- case kZERO: st[0] = '0'; break;
- }
- st[1] = '\0';
- strcat(dispstr,st);
+ case kEIGHT: if (numbase > 8) st[0] = '8'; break;
+ case kNINE: if (numbase > 8) st[0] = '9'; break;
+ case kxA: if (numbase > 10) st[0] = 'A'; break;
+ case kxB: if (numbase > 10) st[0] = 'B'; break;
+ case kxC: if (numbase > 10) st[0] = 'C'; break;
+ case kxD: if (numbase > 10) st[0] = 'D'; break;
+ case kxE: if (numbase > 10) st[0] = 'E'; break;
+ case kxF: if (numbase > 10) st[0] = 'F'; break;
+ }
+
+ if (st[0] == '\0')
+ return;
+ st[1] = '\0';
+ strcat(dispstr,st);
DrawDisplay();
if (clrdisp && keynum != kZERO)
@@ -433,7 +496,7 @@ twoop(int keynum)
}
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
clrdisp=CLR=1;
entered=Dpoint=exponent=0;
@@ -451,7 +514,7 @@ twoop(int keynum)
/* now, if the current op (keynum) is of
higher priority than the lastop, the current
op and number are just pushed on top
- Priorities: (Y^X) > *,/ > +,- */
+ Priorities: (Y^X) > *,/ > +,- > >>,<< > & > ^ > ~ */
if (priority(keynum) > priority(lastop)) {
PushNum(dnum);
@@ -466,10 +529,17 @@ twoop(int keynum)
case kMUL: acc *= dnum; break;
case kDIV: acc /= dnum; break;
case kPOW: acc = pow(acc,dnum); break;
- }
+ case kMOD: acc = (long)acc % (long)dnum; break;
+ case kAND: acc = (long)acc & (long)dnum; break;
+ case kOR: acc = (long)acc | (long)dnum; break;
+ case kXOR: acc = (long)acc ^ (long)dnum; break;
+ case kSHL: acc = (long)acc << (long)dnum; break;
+ case kSHR: acc = (long)acc >> (long)dnum; break;
+ }
+
PushNum(acc);
PushOp(keynum);
- snprintf(dispstr, sizeof(dispstr), "%.8g", acc);
+ format_double(acc);
DrawDisplay();
dnum=acc;
}
@@ -491,7 +561,7 @@ twof(int keynum)
if (!entered)
return;
if (entered==1)
- parse_double(dispstr, "%lf", &dnum);
+ parse_double(&dnum);
acc = PopNum();
switch(keynum) {
case kADD: acc += dnum; break;
@@ -499,9 +569,16 @@ twof(int keynum)
case kMUL: acc *= dnum; break;
case kDIV: acc /= dnum; break;
case kPOW: acc = pow(acc,dnum); break;
- case kXXY: PushNum(dnum);
+ case kXXY: PushNum(dnum); break;
+ case kMOD: acc = (long)acc % (long)dnum; break;
+ case kAND: acc = (long)acc & (long)dnum; break;
+ case kOR: acc = (long)acc | (long)dnum; break;
+ case kXOR: acc = (long)acc ^ (long)dnum; break;
+ case kSHL: acc = (long)acc << (long)dnum; break;
+ case kSHR: acc = (long)acc >> (long)dnum; break;
}
- snprintf(dispstr, sizeof(dispstr), "%.8g", acc);
+
+ format_double(acc);
DrawDisplay();
clrdisp++;
Dpoint = exponent = 0;
@@ -521,7 +598,7 @@ entrf(void)
Dpoint=exponent=0;
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
entered=2;
memop = kENTR;
PushNum(dnum);
@@ -539,7 +616,7 @@ equf(void)
Dpoint=exponent=0;
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
entered=2;
PushNum(dnum);
@@ -562,12 +639,24 @@ equf(void)
case kLPAR: flagPAREN--;
PushNum(acc);
break;
+ case kMOD: acc = (long)acc % (long)dnum;
+ break;
+ case kAND: acc = (long)acc & (long)dnum;
+ break;
+ case kOR: acc = (long)acc | (long)dnum;
+ break;
+ case kXOR: acc = (long)acc ^ (long)dnum;
+ break;
+ case kSHL: acc = (long)acc << (long)dnum;
+ break;
+ case kSHR: acc = (long)acc >> (long)dnum;
+ break;
}
dnum=acc;
PushNum(dnum);
}
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
DrawDisplay();
}
@@ -586,13 +675,13 @@ rollf(void)
if (!entered)
return;
if (entered==1)
- parse_double(dispstr, "%lf", &dnum);
+ parse_double(&dnum);
entered = 2;
lift_enabled = 1;
RollNum(flagINV);
flagINV=0;
clrdisp++;
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
DrawDisplay();
}
@@ -610,7 +699,7 @@ rparf(void)
Dpoint=exponent=0;
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
entered=2;
PushNum(dnum);
@@ -629,6 +718,18 @@ rparf(void)
break;
case kPOW: acc = pow(acc,dnum);
break;
+ case kMOD: acc = (long)acc % (long)dnum;
+ break;
+ case kAND: acc = (long)acc & (long)dnum;
+ break;
+ case kOR: acc = (long)acc | (long)dnum;
+ break;
+ case kXOR: acc = (long)acc ^ (long)dnum;
+ break;
+ case kSHL: acc = (long)acc << (long)dnum;
+ break;
+ case kSHR: acc = (long)acc >> (long)dnum;
+ break;
}
dnum=acc;
PushNum(dnum);
@@ -636,7 +737,7 @@ rparf(void)
(void) PopNum();
flagPAREN--;
entered=2;
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
DrawDisplay();
}
@@ -645,7 +746,7 @@ drgf(void)
{
if (flagINV) {
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
switch (drgmode) {
case DEG: dnum=dnum*M_PI/180.0; break;
case RAD: dnum=dnum*200.0/M_PI; break;
@@ -654,7 +755,7 @@ drgf(void)
entered=2;
clrdisp=1;
flagINV=0;
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
}
flagINV=0;
@@ -685,7 +786,7 @@ memf(int keynum)
{
memop = keynum;
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
entered = 2;
clrdisp++;
lift_enabled = 0;
@@ -698,7 +799,7 @@ oneop(int keynum)
double dtmp;
if (entered==1)
- parse_double(dispstr,"%lf",&dnum);
+ parse_double(&dnum);
entered = 2;
switch (keynum) { /* do the actual math fn. */
@@ -741,6 +842,8 @@ oneop(int keynum)
for (j=1,dnum=1.0; j<=i; j++)
dnum*=(float) j;
break;
+ case kNOT: dnum = ~(long)dnum; break;
+ case kTRUNC: dnum = trunc(dnum); break;
}
if (entered==3) { /* error */
@@ -753,7 +856,7 @@ oneop(int keynum)
clrdisp=1;
flagINV=0;
lift_enabled = 1;
- snprintf(dispstr, sizeof(dispstr), "%.8g", dnum);
+ format_double(dnum);
DrawDisplay();
}
@@ -899,12 +1002,18 @@ priority(int op)
/*******/
{
switch (op) {
- case kPOW: return(2);
+ case kPOW: return(6);
case kMUL:
- case kDIV: return(1);
+ case kDIV:
+ case kMOD: return(5);
case kADD:
- case kSUB: return(0);
- }
+ case kSUB: return(4);
+ case kSHL:
+ case kSHR: return(3);
+ case kAND: return(2);
+ case kXOR: return(1);
+ case kOR: return(0);
+ }
return 0;
}
@@ -915,12 +1024,16 @@ ResetCalc(void)
/********/
{
flagM=flagINV=flagPAREN=0; drgmode=DEG;
+ numbase=(!numbase ? 10 : numbase);
setflag(XCalc_MEMORY, False);
setflag(XCalc_INVERSE, False);
setflag(XCalc_PAREN, False);
setflag(XCalc_RADIAN, False);
setflag(XCalc_GRADAM, False);
setflag(XCalc_DEGREE, True);
+ setflag(XCalc_HEX, False);
+ setflag(XCalc_DEC, True);
+ setflag(XCalc_OCT, False);
strlcpy(dispstr, "0", sizeof(dispstr));
draw(dispstr);
ClearStacks();
diff --git a/xcalc.c b/xcalc.c
index bc262b6..d5d980f 100644
--- a/xcalc.c
+++ b/xcalc.c
@@ -74,7 +74,7 @@ static Display *dpy = NULL; /* connection to the X server */
static Widget toplevel=NULL; /* top level shell widget */
static Widget calculator=NULL; /* an underlying form widget */
static Widget LCD = NULL; /* liquid crystal display */
-static Widget ind[6]; /* mode indicators in the screen */
+static Widget ind[9]; /* mode indicators in the screen */
static char selstr[LCD_STR_LEN]; /* storage for selections from the LCD */
/* checkerboard used in mono mode */
static XtAppContext xtcontext; /* Toolkit application context */
@@ -221,6 +221,18 @@ static void create_display(Widget parent)
/* () - the parenthesis indicator */
ind[XCalc_PAREN] = XtCreateManagedWidget("P", labelWidgetClass, screen,
args, XtNumber(args));
+
+ /* HEX - the hexadecimal (base 16) indicator */
+ ind[XCalc_HEX] = XtCreateManagedWidget("HEX", labelWidgetClass, screen,
+ args, XtNumber(args));
+
+ /* DEC - the hexadecimal (base 16) indicator */
+ ind[XCalc_DEC] = XtCreateManagedWidget("DEC", labelWidgetClass, screen,
+ args, XtNumber(args));
+
+ /* OCT - the octal (base 8) indicator */
+ ind[XCalc_OCT] = XtCreateManagedWidget("OCT", labelWidgetClass, screen,
+ args, XtNumber(args));
}
/*
@@ -240,7 +252,10 @@ static void create_keypad(Widget parent)
"button21","button22","button23","button24","button25",
"button26","button27","button28","button29","button30",
"button31","button32","button33","button34","button35",
- "button36","button37","button38","button39","button40"
+ "button36","button37","button38","button39","button40",
+ "button41","button42","button43","button44","button45",
+ "button46","button47","button48","button49","button50",
+ "button51","button52","button53","button54","button55",
};
register int i;
int n = XtNumber(Keyboard);
diff --git a/xcalc.h b/xcalc.h
index 1492a01..3772ad5 100644
--- a/xcalc.h
+++ b/xcalc.h
@@ -102,6 +102,21 @@ from the X Consortium.
#define kROLL 44 /* roll stack */
#define kNOP 45 /* no operation */
#define kBKSP 46 /* backspace */
+#define kAND 47 /* bitwise and */
+#define kBASE 48 /* base conversion */
+#define kMOD 49 /* modulus */
+#define kNOT 50 /* bitwise not (ones compliment) */
+#define kOR 51 /* bitwise or */
+#define kSHL 52 /* arithmetic shift left */
+#define kSHR 53 /* arithmetic shift right */
+#define kXOR 54 /* bitwise xor */
+#define kTRUNC 55 /* truncate to integer */
+#define kxA 56 /* 0xa */
+#define kxB 57 /* 0xb */
+#define kxC 58 /* 0xc */
+#define kxD 59 /* 0xd */
+#define kxE 60 /* 0xe */
+#define kxF 61 /* 0xf */
#define XCalc_MEMORY 0 /* memory indicator */
#define XCalc_INVERSE 1 /* inverse function indicator */
@@ -109,6 +124,9 @@ from the X Consortium.
#define XCalc_RADIAN 3 /* radian indicator */
#define XCalc_GRADAM 4 /* grad indicator */
#define XCalc_PAREN 5 /* parenthesis indicator */
+#define XCalc_HEX 6 /* hexadecimal (base 16) indicator */
+#define XCalc_DEC 7 /* decimal (base 10) indicator */
+#define XCalc_OCT 8 /* octal (base 8) indicator */
/* actions.c */
extern XtActionsRec Actions[];
@@ -121,6 +139,7 @@ extern void fail_op(void);
extern int pre_op(int keynum);
extern void post_op(void);
+extern void change_base(void);
extern void numeric(int keynum);
extern void bkspf(void);
extern void decf(void);