Reading REAL's from file in FORTRAN 77 - odd results - file

I'm currently messing around in FORTRAN 77 and I've ran into a problem that I can't seem to figure out. I'm trying to read from a file that looks similar to below:
000120 Description(s) here 18 7 10.15
000176 Description(s) here 65 20 56.95
...
The last column in each row is a monetary amount (never greater than 100). I am trying to read the file by using code similar to below
integer pid, qty, min_qty
real price
character*40 descrip
open(unit=2, file='inventory.dat', status='old')
read(2, 100, IOSTAT=iend) pid, descript, qty, min_qty, price
100 format(I11, A25, I7, I6, F5)
Everything seems to be read just fine, except for the last column. When I check the value of price, say for example, for the second line; instead of getting 56.95 I get something like 56.8999999999.
Now, I understand that I might have trailing 9's or whatnot because it's not totally precise, but shouldn't it be a little closer to 95 cents? Maybe there's something that I'm doing wrong, I'm not sure. Hopefully I'm just not stuck with my program running like this! Any help is greatly appreciated!

Is that exactly the code you use to read the file? Do you have "X" formats to align the columns? Such as (I11, A25, 2X, I7, 3X, I6, 3X, F5) (with made up values). If you got the alignment off by one and read only "56.9" for "56.95", then floating point imprecision could easily give you 56.89999, which is very close to 56.9
You could also read the line into a string and read the numbers from sub-strings -- this would require only precisely identifying the location of the string. Once the sub-strings contained only spaces and numbers, you could use a less-finicky IO directed read: read (string (30:80), *) qty, min_qty, price.

Related

Ive got a pipe that consists of 5 pieces, each including 5 properties

Inlet -> front -> middle -> rear -> outlet
Those five properties have a value anything between 4 - 40. Now i want to calculate a specific match for each of those values that is either a full 10 or a 5 when a single property is summed from each pipe piece. There might be hundreds of different pipe pieces all with different properties.
So if i have all 5 pieces and when summed, their properties go like 54,51,23,71,37. That is not good and not what im looking.
Instead 55,50,25,70,40. That would be perfect.
My trouble is there are so many of the pieces that it would be insane to do the miss'matching manually, and new ones come up frequently.
I have manually inserted about 100 of these already into SQLite, but should be easy to convert into any excel or other database formats, so answer can be related to anything like mysql or googlesheets.
I need the calculation that takes every piece in account and results either in "no match" or tells me the id of each piece that is required for a match and if multiple matches are available, it separates them.
Edit: Even just the math needed to do this kind of calculation would be a lot of help here, not much of a math guy myself. I guess there should be a reference piece i need to use and then that gets checked against every possible scenario.
If the value you want to verify is in A1, use: =ROUND(A1/5,0)*5
If the pipes may not be shorter than the given values, use =CEILING(A1,5)

SQL Server: round a percentage to nearest whole number

I've looked at some of the answers here, and I keep getting stuck. I'm a brand new beginner.
I have a simple select statement
SELECT (100.0*(CURRENRL)/(CAPACITY)) AS "OCCUPANCY RATE"
FROM COURSE, LOCATION
WHERE LOCATION.LOCID=COURSE.LOCID
returns a column
90.000000000000
100.000000000000
80.000000000000
100.000000000000
100.000000000000
59.523809523809
66.666666666666
28.571428571428
76.190476190476
83.333333333333
23.333333333333
I'm just trying to round to the nearest whole number.
Such that I get output like:
90
100
80
100
100
60
67
...
I've tried to use ROUND and CAST, but end up with errors every time. I can post the errors if necessary, but my guess is that this should be simple and I'm missing some formatting or similar from the other questions I've looked at here on SO.
If I do:
ROUND(100.0*(CURRENRL)/(CAPACITY), 0) AS "OCCUPANCY RATE"
I get a lot of decimal places.
If I do:
ROUND(100*(CURRENRL)/(CAPACITY), 0) AS "OCCUPANCY RATE"
I get a nice whole integer, but it doesn't seem to round correctly. For instance, I get 59 instead of 60 for the 6th number, and 66 instead of 67 for the 7th number, etc.
How about a combination using cast and round? after rounding off, switch it to INT to get the whole number.
SELECT **CAST(** _ROUND(100.0*(CURRENRL)/(CAPACITY)), 0)_ **AS INT)** AS "OCCUPANCY RATE"
FROM COURSE, LOCATION
WHERE LOCATION.LOCID=COURSE.LOCID
BUT also tested the edited answer of E Alexis T using ceiling and it also gives your desired answer. It's far better than my answer in terms of shorter code :) It should be your choice. It just has a flaw in rounding lower than 5. example 123.39 still goes to 124.
You can use SELECT CEILING(66.666666666666) gives 67, from your statement:
SELECT CEILING(100*(CURRENRL)/(CAPACITY)) AS "OCCUPANCY RATE"
FROM COURSE, LOCATION
WHERE LOCATION.LOCID=COURSE.LOCID
You could just do it as below.
First, round your results, then you convert it to int. It will automatically remove the zeros to the right
select convert(int,round((100.0*(CURRENRL)/(CAPACITY)) ,0)) AS "OCCUPANCY RATE"
FROM COURSE, LOCATION
WHERE LOCATION.LOCID=COURSE.LOCID

SQL CONVERT STRING

I do struggle with some of these conversions, so I do apologize, I have asked a similar question in the past, but just can't get my head around how to achieve this.
So a value of 50.00 is currently being exported into the following format -
000000000000050000
A value of 25.99 would look like
000000000000025990
This is a 18 character field where any leading characters are padded with a zero.
What I am trying to do is convert that to a 19 character string - still with leading zeros - but the value of 50 or 25.99 is slightly different -
000000000000050000 becomes 0000000000000005000
000000000000025990 becomes 0000000000000002599
Any help would be greatly appreciated.
You would appear to want:
select '00' + left(str, 17)
This is a very strange format. Perhaps you should consider using numeric/decimal, which can accurately represent the number.
A lot of assumptions go into this answer, but...
SELECT '00'+LEFT(OriginalField, 17)
That would truncate your original 18th character and simply put two more zero's on the front.
The solution is not so simple if you need to potentially round up the 17th character.

Parsing variable length input file into objects - suggestions?

I have been given the task of writing a small ATM program where. The program upon receives an input file, runs through the file, carrying out instructions.
The input file is of the following format:
8000
 
12345678 1234 1234
500 100
B
W 100
 
87654321 4321 4321
100 0
W 10
The first line is the total cash held in the ATM followed by a blank line. The remaining input represents zero or more user sessions. Each session consists of:
The user's account number, correct PIN and the PIN they actually entered. These are separated by spaces.
Then, on a new line, the customer's current balance and overdraft facility.
Then, one or more transactions, each on a separate line. These can be one of the following types:
Balance inquiries, represented by the operation code B.
Cash withdrawals, represented by the operation code W followed by an amount.
A blank line marks the end of a user session.
I am able to write the part of the program that carries out the transactions and outputs results.
What I need help on is parsing the input file in a meaningful way (possibly into objects). I am having issues with the fact the input is of variable length, making looping very difficult.
Can anyone push me in the right direction? I'm not just being lazy looking for the answer. I just need a nudge. I'm stuck on this for half a day now.
Thanks a million.
You can use regular expressions to parse each line, it looks like you can safely match each line uniquely.
12345678 1234 1234 = ^(\d+)\s(\d+)\s(\d+)$
500 100 = ^(\d+)\s(\d+)$
B = ^B$
W 100 = ^W\s(\d+)
Since the first line is know, just convert it to an Integer manually.
Then walk the file, line by line, on each empty line start trying to parse the next lines with each of the regular expressions until you have a match. Use the regular expression groups () to extract the relevant data. Handle them accordingly. When you get an empty line, reset everything and start parsing with the regular expressions again.
Read up on Event Driven applications, which is what this is, the apparently loop in reading the file is a red-herring.
The blank lines represent the starts of logical set of events. Each line then represents an atomic event, which should easily map to a function/method call.

What is the international format for telephone numbers

Is there a format for phone numbers which all numbers will fit into? (something that is more flexible than 3 numbers for the area code and 7 numbers for the rest)
This is tagged as data-modeling.. so I'll address that aspect.
Telephone numbers, regardless of country, should always be stored as a string without formatting (eg. "9083429876").
I see people trying to store these as a string WITH formatting.. and that usually leads to disaster. Somewhere, someone will want those numbers formatted differently. Then you have to write not only a formatting function for them, but an unformatting function as well. Yowsa.
I also see people trying to store these as INT64 (or BIGINT). Well, fine, but why? Noone ever DISPLAYS unformatted telephone numbers.. and to format it you have to turn it into a string. Some try to argue that its for sorting purposes, but that doesn't fly either. Sorting phone numbers is NEVER a useful operation. Filtering numbers based on area code is useful - but returning all the numbers in numerical sorted order? Never useful.
The third bad practive I see is people that store each component of the number in separate fields. Again, not good. The moment you start poking international numbers in there those fields become meaningless.. As an example: do you think Senegal uses Area Codes?
So as a parting thought I leave you with this: Since each country will have its own set of numbers (symbols really) - thought and care should be given to how one till format them for display.
http://en.wikipedia.org/wiki/E.164
http://www.kropla.com/dialcode.htm
Edit: should check what I paste before I actually submit.
The format for all phone numbers is:
country code (1-3 digits)
the rest
number of digits for a phone number should be 15 or less.
See also wikipedia
Always store the number with a country code so that it is unambiguous and can be formatted correctly for the reader upon display.

Resources