mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
381 lines
7.3 KiB
Plaintext
381 lines
7.3 KiB
Plaintext
/*
|
|
* hms - calculate in hours, minutes, and seconds
|
|
*
|
|
* Copyright (C) 2010,2021 Landon Curt Noll
|
|
*
|
|
* Calc is open software; you can redistribute it and/or modify it under
|
|
* the terms of the version 2.1 of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* Calc is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
* Public License for more details.
|
|
*
|
|
* A copy of version 2.1 of the GNU Lesser General Public License is
|
|
* distributed with calc under the filename COPYING-LGPL. You should have
|
|
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Under source code control: 2010/09/01 17:14:55
|
|
* File existed as early as: 2010
|
|
*
|
|
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
|
*/
|
|
|
|
|
|
obj hms {hour, min, sec};
|
|
|
|
define hms(hour, min, sec)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* default missing args to 0 */
|
|
if (isnull(sec)) {
|
|
sec = 0;
|
|
}
|
|
if (isnull(min)) {
|
|
min = 0;
|
|
}
|
|
|
|
/* load object */
|
|
ans.hour = hour;
|
|
ans.min = min;
|
|
ans.sec = sec;
|
|
|
|
/* return properly formed object */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_add(a, b)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* initialize value to 1st arg */
|
|
if (istype(a, ans)) {
|
|
/* 1st arg is hms object, load it */
|
|
ans.hour = a.hour;
|
|
ans.min = a.min;
|
|
ans.sec = a.sec;
|
|
} else {
|
|
/* 1st arg is not hms, assume scalar hours */
|
|
ans.hour = a;
|
|
ans.min = 0;
|
|
ans.sec = 0;
|
|
}
|
|
|
|
/* add value of 2nd arg */
|
|
if (istype(b, ans)) {
|
|
/* 2nd arg is hms object, add it */
|
|
ans.hour += b.hour;
|
|
ans.min += b.min;
|
|
ans.sec += b.sec;
|
|
} else {
|
|
/* 2nd arg is not hms, add scalar hours */
|
|
ans.hour += b;
|
|
}
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_neg(a)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* negate argument */
|
|
if (istype(a, ans)) {
|
|
/* 1st arg is hms object, load it */
|
|
ans.hour = -a.hour;
|
|
ans.min = -a.min;
|
|
ans.sec = -a.sec;
|
|
} else {
|
|
/* 2nd arg is not hms, negate scalar hours */
|
|
ans.hour = -a;
|
|
ans.min = 0;
|
|
ans.sec = 0;
|
|
}
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_sub(a, b)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* initialize value to 1st arg */
|
|
if (istype(a, ans)) {
|
|
/* 1st arg is hms object, load it */
|
|
ans.hour = a.hour;
|
|
ans.min = a.min;
|
|
ans.sec = a.sec;
|
|
} else {
|
|
/* 1st arg is not hms, assume scalar hours */
|
|
ans.hour = a;
|
|
ans.min = 0;
|
|
ans.sec = 0;
|
|
}
|
|
|
|
/* subtract value of 2nd arg */
|
|
if (istype(b, ans)) {
|
|
/* 2nd arg is hms object, subtract it */
|
|
ans.hour -= b.hour;
|
|
ans.min -= b.min;
|
|
ans.sec -= b.sec;
|
|
} else {
|
|
/* 2nd arg is not hms, subtract scalar hours */
|
|
ans.hour -= b;
|
|
}
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_mul(a, b)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* hms object multiplication */
|
|
if (istype(a, ans) && istype(b, ans)) {
|
|
ans.hour = hms_abs(a) * hms_abs(b);
|
|
ans.min = 0;
|
|
ans.sec = 0;
|
|
|
|
/* scalar multiplication */
|
|
} else if (istype(a, ans)) {
|
|
ans.hour = a.hour * b;
|
|
ans.min = a.min * b;
|
|
ans.sec = a.sec * b;
|
|
} else {
|
|
ans.hour = b.hour * a;
|
|
ans.min = b.min * a;
|
|
ans.sec = b.sec * a;
|
|
}
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_print(a)
|
|
{
|
|
local obj hms ans; /* temp object for hms type testing */
|
|
|
|
/* firewall - arg must be a hms object */
|
|
if (! istype(a, ans)) {
|
|
quit "hms_print called with non hms object";
|
|
}
|
|
|
|
/* print in hms form */
|
|
print a.hour : ':' : a.min : ':' : a.sec :;
|
|
}
|
|
|
|
|
|
define hms_abs(a)
|
|
{
|
|
local obj hms ans; /* temp object for hms type testing */
|
|
local hour; /* return scalar value */
|
|
|
|
/* firewall - just absolute value non hms objects */
|
|
if (! istype(a, ans)) {
|
|
return abs(a);
|
|
}
|
|
|
|
/* compute hours */
|
|
hour = a.hour + a.min / 60 + a.sec / 3600;
|
|
|
|
/* return hours */
|
|
return hour;
|
|
}
|
|
|
|
|
|
define hms_norm(a)
|
|
{
|
|
local obj hms ans; /* temp object for hms type testing */
|
|
local hour; /* hours */
|
|
|
|
/* firewall - arg must be a hms object */
|
|
if (! istype(a, ans)) {
|
|
quit "hms_norm called with non hms object";
|
|
}
|
|
|
|
/* square hours (norm is the square of absolute value */
|
|
hour = hms_abs(a);
|
|
|
|
/* return hours */
|
|
return hour*hour;
|
|
}
|
|
|
|
|
|
define hms_test(a)
|
|
{
|
|
local obj hms ans; /* temp value */
|
|
|
|
/* firewall - arg must be a hms object */
|
|
if (! istype(a, ans)) {
|
|
quit "hms_test called with non hms object";
|
|
}
|
|
|
|
/* return false of non-zero */
|
|
ans = fixhms(a);
|
|
if (ans.hour == 0 && ans.min == 0 && ans.sec == 0) {
|
|
/* false */
|
|
return 0;
|
|
}
|
|
/* true */
|
|
return 1;
|
|
}
|
|
|
|
|
|
define hms_int(a)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* firewall - arg must be a hms object */
|
|
if (! istype(a, ans)) {
|
|
quit "hms_int called with non hms object";
|
|
}
|
|
|
|
/* normalize the argument */
|
|
ans = fixhms(a);
|
|
|
|
/* truncate to the nearest second */
|
|
ans.sec = int(ans.sec);
|
|
|
|
/* return value to the nearest second */
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_frac(a)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* firewall - arg must be a hms object */
|
|
if (! istype(a, ans)) {
|
|
quit "hms_frac called with non hms object";
|
|
}
|
|
|
|
/* normalize the argument */
|
|
ans = fixhms(a);
|
|
|
|
/* remove all but fractional seconds */
|
|
ans.hour = 0;
|
|
ans.min = 0;
|
|
ans.sec = frac(ans.sec);
|
|
|
|
/* return value to the second fraction */
|
|
return ans;
|
|
}
|
|
|
|
|
|
define hms_rel(a,b)
|
|
{
|
|
local abs_a, abs_b; /* scalars of the arguments */
|
|
|
|
/* compute scalars of the arguments */
|
|
abs_a = hms_abs(a);
|
|
abs_b = hms_abs(b);
|
|
|
|
/* return the comparison */
|
|
return cmp(abs_a, abs_b);
|
|
}
|
|
|
|
|
|
define hms_cmp(a,b)
|
|
{
|
|
local abs_a, abs_b; /* scalars of the arguments */
|
|
|
|
/* compute scalars of the arguments */
|
|
abs_a = hms_abs(a);
|
|
abs_b = hms_abs(b);
|
|
|
|
/* return the equality comparison */
|
|
return (abs_a == abs_b);
|
|
}
|
|
|
|
|
|
define hms_inc(a)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* increment a hms object */
|
|
if (istype(a, ans)) {
|
|
ans = a;
|
|
++ans.sec;
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
/* increment a scalar */
|
|
return a+1;
|
|
}
|
|
|
|
|
|
define hms_dec(a)
|
|
{
|
|
local obj hms ans; /* return value */
|
|
|
|
/* decrement a hms object */
|
|
if (istype(a, ans)) {
|
|
ans = a;
|
|
--ans.sec;
|
|
|
|
/* return normalized result */
|
|
ans = fixhms(ans);
|
|
return ans;
|
|
}
|
|
|
|
/* decrement a scalar */
|
|
return a-1;
|
|
}
|
|
|
|
|
|
define fixhms(a)
|
|
{
|
|
local obj hms ans; /* temp value */
|
|
|
|
/* firewall */
|
|
if (! istype(a, ans)) {
|
|
quit "attempt to fix a non hms object";
|
|
}
|
|
|
|
/* force minutes to be integral */
|
|
a.min += frac(a.hour) * 60;
|
|
a.hour = int(a.hour);
|
|
|
|
/* force hours to be integral */
|
|
a.sec += frac(a.min) * 60;
|
|
a.min = int(a.min);
|
|
|
|
/* carry excess seconds into minutes */
|
|
a.min += a.sec // 60;
|
|
a.sec %= 60;
|
|
|
|
/* carry excess minutes into hours */
|
|
a.hour += a.min // 60;
|
|
a.min %= 60;
|
|
|
|
/* round hours by day */
|
|
a.hour %= 24;
|
|
|
|
/* return normalized result */
|
|
return a;
|
|
}
|
|
|
|
if (config("resource_debug") & 3) {
|
|
print "obj hms {hour, min, sec} defined";
|
|
}
|