getdate.y grammar doubts - c

http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/usr.bin/tar/Attic/getdate.y?rev=1.9.12.1;content-type=text%2Fplain;hideattic=0
I am trying to understand how yyTimezone is calculated in code below:
| bare_time '+' tUNUMBER {
/* "7:14+0700" */
yyDSTmode = DSToff;
yyTimezone = - ($3 % 100 + ($3 / 100) * 60);
}
| bare_time '-' tUNUMBER {
/* "19:14:12-0530" */
yyDSTmode = DSToff;
yyTimezone = + ($3 % 100 + ($3 / 100) * 60);
}
How I understand is, lets say the timestamp is 2011-01-02T10:15:20-04:00; this means its 0400 hours behind UTC. So to convert it into UTC, you add 0400 hours to it and it becomes 2011-01-02T14:15:20. Is my understanding correct?
How is that achieved in the codeblock I pasted above?

The input would encode the offset like -0400. The 0400 part of that would be returned as the tUNUMBER token (presumably holding an unsigned value). This token is matched by the grammar rules, and can be used as $3.
To get the actual offset in minutes from the value 400, you first have to split it up in two halves. The hours part can be obtained with $3 / 100 (ie. 4), and the minutes part with $3 % 100 (ie. 0). Since there are 60 minutes in an hour, you multiply the hours by 60, and add the minutes to that ($3 % 100 + ($3 / 100) * 60), which would give the value 240. Then all that's left, is to add the sign, and store it in yyTimezone.
After all that, yyTimezone will contain the timezone offset in minutes.

Related

Calculating the day of the week using Gauss Algorithm

I'm trying to create a program which will calculate the same date in three different ways. I'm currently stuck on calculating the day of the week, as I need this to calculate the ISO week day. I've got an algorithm that I can use, and it is the one which I've got in my code, with the only difference being that the % sign in my code is replaced by the word "mod" in the algorithm.
When I run this, I get an error saying "Expected expression before % token". I've looked this up but didn't find any results. I've also tried to look at other ways of doing it, and found the Sakomoto Algorithm, but I don't exactly understand how that works. For a possible solution, I was thinking that I maybe need to create a function called mod, but I'm not entirely sure what I would need to put in there.
int day_of_the_week(int year)
{
int week_day;
week_day = %(1+5 * %(year - 1, 4) + 4 * %(year - 1, 100) + 6 * %(year-1,
400), 7);
printf("The day of the week is %d\n", week_day);
return 0;
}
Gauss'
R(1 + 5R(A - 1, 4) + 4R(A - 1, 100) + 6R(A - 1, 400), 7)
should be equivalent to
int week_day = (1 + 5 * (year - 1) % 4) + 4 * ((year - 1) % 100) + 6 * ((year - 1) % 400) % 7;

Issue while adding values in SQL Server

Please read again till end (description updated)
I want something like this.
ex :
if (7200 / 42) is float then
floor(7200/42) + [7200 - {(floor(7200/42)) * 42}] / 10 ^ length of [7200 - {(floor(7200/42)) * 42}]
STEP : 1 => 171 + ((7200 - (171*42))/10 ^ len(7200-7182))
STEP : 2 => 171 + ((7200 - 7182)/10 ^ len(18))
STEP : 3 => 171 + (18/10 ^ 2)
STEP : 4 => 171 + (18/100)
STEP : 5 => 171 + 0.18
STEP : 6 => 171.18
I have written the code in SQL which actually works perfectly but the addition of 171 + 0.18 only gives 171
IF I can get "171/18" instead of "171.18" as string then it'd also be great. (/ is just used as separator and not a divison sign)
Following is the code I written
Here,
(FAP.FQTY + FAP.QTY) = 7200,
PRD.CRT = 42
(values only for example)
select
case when PRD.CRT <> 0 then
case when (FAP.FQTY + FAP.QTY)/PRD.CRT <> FLOOR((FAP.FQTY + FAP.QTY)/PRD.CRT) then --DETERMINE WHETHER VALUE IS FLOAT OR NOT
(floor((FAP.FQTY + FAP.QTY)/PRD.CRT)) +
((FAP.FQTY + FAP.QTY) - floor((FAP.FQTY + FAP.QTY)/PRD.CRT) * PRD.CRT) /
POWER(10, len(floor((FAP.FQTY + FAP.QTY) - floor((FAP.FQTY + FAP.QTY)/PRD.CRT) * PRD.CRT)))
else
(FAP.FQTY + FAP.QTY)/PRD.CRT -- INTEGER
end
else
0
end
from FAP inner join PRD on FAP.Comp_Year = PRD.Comp_Year and
FAP.Comp_No = PRD.Comp_No and FAP.Prd_Code = PRD.Prd_Code
I got all the values correct till 171 + 0.1800 correct but after that I am only receiving 171 in the addition. I want exactly 171.18.
REASON FOR THIS CONFUSING CALCULATION
Its all about accounting
Suppose, a box(or a cartoon) has 42 nos. of items.
A person sends 7200 items. how many boxes he has to send?
So that will be (7200/42) = 171.4257.
But boxes cannot be cut (its whole number i.e 171).
so 171 * 42 ie 7182 items.
Remaining items = 7200 - 7182 = 18.
So answer is 171 boxes and 18 items.
In short 171.18 or "171/18"
Please help me with this..
Thank you in advance.
Recognise that you're not producing an actual numeric result, I'd describe it as unhealthy to try to keep it using such a datatype1.
This produces the strings you're seeking, if I've understood your requirement:
;With StartingPoint as (
select 7200 as Dividend, 42 as Divisor
)
select
CONVERT(varchar(10),Quotient) +
CASE WHEN Remainder > 0 THEN '.' + CONVERT(varchar(10),Remainder)
ELSE '' END as FinalString
from
StartingPoint
cross apply
(select Dividend/Divisor as Quotient, Dividend % Divisor as Remainder) t
(Not tested for negative values. Some adjustments may be required. Technically % computes the modulus rather than the remainder, etc)
1Because someone might try and add two of these values together and I doubt that produces a correct result, not even necessarily if using the same Divisor to compute both.
Just another idea about how to calculate it.
Simple calculate the whole boxes.
And concatinate a dot with the remaining items (using a modulus).
Wrapped it all up in a CASE WHEN (or IIF) to avoid the divide by zero.
Example snippet:
declare #TestTable table (FQTY numeric(18,2), QTY numeric(18,2), CRT numeric(18,0));
insert into #TestTable (FQTY,QTY,CRT) values
(5000, 2200, 42),
(5000, 2200, 0),
( 100, 200, 10);
select *,
(CASE
WHEN CRT>0
THEN CONCAT(CAST(FLOOR((FQTY+QTY)/CRT) as INT),'/',CAST((FQTY+QTY)%CRT as INT))
ELSE '0'
END) AS Boxes
from #TestTable;
Result:
FQTY QTY CRT Boxes
------- ------- --- ------
5000.00 2200.00 42 171/18
5000.00 2200.00 0 0
100.00 200.00 10 30/0
The CONCAT returns a varchar, and so does the CASE WHEN.
But you could wrap that CASE WHEN in a CAST.
You're getting an automatic type conversion from int to decimal(10,0) which is probably not what you want.
https://learn.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-2017
Check out the "Caution" box.
If you want a specific amount of precision, you'll need to explicitly cast() the values to the desired data type.
if i understand your logic correctly you want the remainder of 7200 divide by 42 and the remainder is to divide by 100
declare
#dividend int = 7200,
#divisor int = 42
select (#dividend / #divisor)
+ convert(decimal(10,4),
(#dividend % #divisor) * 1.0 / power(10, len(#dividend % #divisor)))
EDIT: change to handle the 10^len(remainder)

Get Time Difference without if else statement

C Time Difference
scanf ("%2d %2d", &shours, &sminutes);
printf ("Enter End Time : ");
scanf ("%2d %2d", &ehours, &eminutes);
printf ("\nTIME DIFFERENCE\n");
tohours = ehours - shours;
printf("Hour(s) : %2d", tohours);
tominute = eminutes - sminutes;
printf("\nMinute(s): %2d ", tominute);
How can I make my output like this? When I try to run my code the minutes output is -59 instead of 1 and my hours is the one who got the output "1"
P.S. without using the if else statements
Use (some sort of) timestamps, by turning your hours and minutes variables into one, e.g:
stime = shours * 60 + sminutes;
etime = ehours * 60 + eminutes;
then calculate de difference of that
totime = etime - stime;
then convert that back into hours and minutes
tominutes = totime % 60;
tohours = (totime - tominutes) / 60;
(integer division will take care of rounding down)
Not the most elaborated solution, but I guess you're looking for an beginners-friendly solution
Edit
speaking of beginner-friendly: the % is the modulus operator that returns the remainder of a division. So when you divide 119 by 60 it returns 59. And yes, you could also just get the hours from dividing totime by 60 and let the integer division do the job, but it's nicer (read: clearer to read what's going on) when you divide (totime - tominutes) because it's like the missing part to the line with the modulus

Convert an array of timestamps to seconds in Matlab

I'm new to SO and Matlab so please excuse any transgressions.
I'm trying to convert a seemingly simple array of timestamp strings to an equivalent array of seconds.
I wrote a this function:
% Function to calculate seconds from a timestamp in the following format:
% ddd hh:mm:ss.SSSS (example: 123 12:59:00.9999)
function a = TimestampToS(stamp)
% Uses the "named tokens" facility of MATLAB's "regexp" function.
expr = ['(?<ddd>\d+)' ... % ddd
' ' ... % Space " " separator
'(?<hh>\d+)' ... % hh
':' ... % Colon ":" separator
'(?<mm>\d+)' ... % mm
':' ... % Colon ":" separator
'(?<ss>\d+)' ... % ss
'.' ... % Dot "." separator
'(?<SSSS>\d+)']; % SSSS
parsedStamp = regexp(stamp, expr, 'names');
a = (str2double(parsedStamp.ddd) * 86400) + ...
(str2double(parsedStamp.hh) * 3600) + ...
(str2double(parsedStamp.mm) * 60) + ...
(str2double(parsedStamp.ss)) + ...
(str2double(parsedStamp.SSSS) * 0.0001);
It works great for an individual string:
>> TimestamptoS('123 12:59:00.9999')
ans =
1.067394099990000e+007
But if I try to use a cell array I get:
Attempt to reference field of non-structure array.
How can I get an array of seconds? I have tried all kinds of conversions of the input data and "parsedStamp" but nothing works. I don't understand Matlab or its matrix notation well enough. Any help gratefully received!
PS This is not a regexp question, no replies about regexp please!
You can do it very easily without modifying your function, by using cellfun. This essentially extracts each cell of the cell array and passes it to your function.
>> cellArray = {'123 12:59:00.9999','130 12:59:00.9999'}; % for example
>> cellfun(#TimestampToS,cellArray)
ans =
1.0e+007 *
1.067394099990000 1.127874099990000

In c , how do I make 1200 / 500 = 3

In C , how do I make 1200 / 500 = 3.
I'm doing a homework assignment.
Shipping Calculator: Speedy Shipping company will ship your package based on how much it weighs and how far you are sending the package. They will only ship small packages up to 10 pounds. You need to have a program that will help you determine how much they will charge. The charges are based on each 500 miles shipped. They are not pro-rated, i.e., 600 miles is the same charge as 900 miles.
Here is the table they gave you:
Package Weight--------------------------Rate per 500 miles shipped
2 pounds or less------------------------$1.50
More than 2 but not more than 6---------$3.70
More than 6 but not more than 10--------$5.25
Here is one test case.
Test Case Data:
Weight: 5.6 pounds
Miles: 1200 miles
Expected results:
Your shipping charge is $11.10
My answer keeps coming out to 7.40
Are you trying to round up? Before dividing, you could add 499 to the number that is being divided.
(0 + 499) / 500 -> 0
(1 + 499) / 500 -> 1
(1200 + 499) / 500 -> 3
This will round up.
Say you want to get a ceiling division a by b (in your example a = 1200 b = 500).
You can do it in integer arithmetic like this.
result = (a + b - 1) / b;
Or you could use floating point numbers and do it like this (probably a bad idea)
result = (int) ceil( (double) a / b );
The thing is that as this is a homework, you could just make it up in small steps:
if( a % b == 0 ) {
result = a / b;
} else {
result = a / b + 1;
}
Another advantage of this code is that it actually doesn't overflow for too big as, but this is not relevant in this case, I guess.
I'd suggest using the mod and truncate functions. If mod comes out zero, it's fine, otherwise truncate and add 1.
You have to use the ceiling of the division. This will round the quotient up to the next integer.
So when you are trying to find the number of 500-mile increments, you have to round the quotient up to the next integer.
Alternatively, (and inefficiently), you could increment the number of miles by 1, until it is divisible by 500...that is, while ( (q = x_miles++%500) != 0 ) {} . Then multipy q by the rate to get your answer (That is also assuming you will have an integer number of miles).
You could also use the stdlib div function. This might be nice if you only wanted integer math and specifically wanted to avoid floating point math.
http://www.cplusplus.com/reference/clibrary/cstdlib/div/
#include <stdlib.h>
int foo(void)
{
div_t result = div(1200, 500);
return result.quot + (0 < result.rem);
}
[EDIT1]
From your code you would implement this part as follows:
if ( weight <= 5.6 )
{
int multiplier = (int) miles / 500;
if( ((int)miles % 500) > 0)
multiplier++;
rate370 = (double)multiplier * 3.7;
printf("Your total cost : %.2lf\n", rate370);
}
[ORIGINAL]
In "integer land" 1200 / 3 should equal to 2.
for what it "seems" you want try this:
int multFiveHundreds = (int)totalWeight / 500;
if(multFiveHundreds % 500 > 0)
multFiveHundreds++;

Resources