I have legacy fortran code in which I am printing some numbers to a file, without a format statement. Now some of this output looks like this:
ah !!!!!!!!!!!!!!!!!!!!!!!!!! afn !!!!!!!!!!!!!!!!!!!!!!!!!!
ah !!!!!!!!!!!!!!!!!!!!!!!!!! afn +*************************
ah !!!!!!!!!!!!!!!!!!!!!!!!!! afn +*************************
ah !!!!!!!!!!!!!!!!!!!!!!!!!! afn !!!!!!!!!!!!!!!!!!!!!!!!!!
ah !!!!!!!!!!!!!!!!!!!!!!!!!! afn 6.31304569736211807
The corresponding code is:
write(6,*) 'ah', ah(nzaehl),'afn',afn(nzaehl)
The ah and afn are just arrays that should contain real numbers. This output is for debugging purposes to find out what these arrays really look like. As it is, as long as I don't know what the exclamation marks mean, I don't really know where it goes wrong.
The lines that contain asteriscs are numbers that are too big, if I understand correctly, but what do the exclamation marks mean? I can't find anything on google for some reason, so I would really appreciate an explanation.
The compiler used is f90. At least that's what is called in the makefile.
I finally found the culprit, these weird exclamation marks are apparently the result of dividing 0 by 0, i.e. NaN. Why it doesn't just say "NaN" is a mystery to me.
I really don't know how many people are using the same compiler, judging from the comments not many, but I thought I'd put this information out there for future reference.
Related
The following code has to check for an 'e' value such that the gcd(h,e)=1. Where 1
module great(p,q,e,d);
input p,q;
output e,d;
reg e,d;
h=((p-1)*(q-1));
always
begin
for(e=2;e<h;e=e+1)
begin
g1=gcd(h,e);
if(g1==1)
return e;
If, by "return a value", you mean spit out a value you can use in another module, you would use the output of this module as your "return" value. But even ignoring the return e, I don't think your code will work if you tried to run it, because it is too much like a programming language. There's several major things wrong:
You already declared output e,d so you can't declare two reg with the same name. You probably want output reg e,d instead.
You didn't declare a type for h or g1.
You have a for loop for e but e can never be anything other than 0 or 1 because you didn't set a size for it, so by default it is only 1-bit long. Even if it was big enough that you could increment it past 1, it's a wire type by default, and you can't make those kind of increments to a wire directly.
I assume gcd is some module you made somewhere else, but this isn't how you interconnect modules together. You can't call it like it's a function. You have to use wire and reg to connect the inputs and outputs of two modules together, almost like you're plugging components in.
Those are what stick out the most to me, anyway. I think you are coding your Verilog as if it were Python and that's what's causing these misunderstandings. Verilog is very, very different.
I am a quite new programmer, and I sometimes have really dumb questions,
In a few weeks I am supposed to give back this big semester project and I would have liked a bit of help for my optimization.
Somewhere I needed to get a Quantitiy (class derived from a double) and strip it down to a just a number without integers and print it in a window (I dont have the slightest clue how the latter works, it was given to us by the teacher, but it's not the problem here).
And so I created two variables to do so, which gave me something like this:
int lil_patate=q_nutriments;
string patate(to_string(lil_patate));
And I would have like to set that in a single line, writing that;
string patate(to_string(int lil_patate=q_nutriments));
which of course doesnt work, as I expected, but I would have loved a bit of help to get something working that would be simpler than the first version but doing the same thing,
Thanks for the help and have a nice day :)
Humphrey
If you need to be able to reference lil_patate elsewhere in your code then you can't make this factorisation at all. If you don't need to refer to lil_patate elsewhere then get rid of it and initialise patate directly from q_nutrients:
string patate(to_string(q_nutriments));
However, while this may improve the readability of the code, it doesn't represent an optimisation in any technical sense.
I want make a function as I type and read it as a function. For example, if I type x+y, then f(x,y)=x+y. Is this possible? The following code does not work.
real function f(x,y)
real x,y
write(6,*) "type f(x,y)"
read*, f
return
end
Yes, you can, but your syntax is a bit off.
PROGRAM READFUNC
REAL x,y,F,res
res = F(x,y)
WRITE(*,*) res
END
REAL FUNCTION F(x,y)
REAL x,y
WRITE (*,*) "Type in"
READ (*,*) F
RETURN
END
note that I compiled this w/ gfortran so I'm not sure if it uses any F90+ extensions or not.
EDIT After reading your edits, I see that this isn't what you want; you want some kind of eval/parser. In general this is not a trivial thing. You're going to have to do some kind of token parsing work.
However there are libraries that can do this for you that are already written.
See this article for an example of where to look for more research.
F(X,Y)=X+Y
99 READ(*,*)X,Y
WRITE(*,*)F(X,Y)
GO TO 99
You enter 3 4 or 3,4 and you get out 7
I have some Fortran 77 source files that I'm trying to convert from a non-standard STRUCTURE and RECORD syntax to the standardized Fortran 90 TYPE syntax. One tricky aspect of this is the different way that structure members are addressed.
Non-standard:
s.member = 1
Standard:
s%member = 1
So, I need to trap all uses of periods in these sort of scenarios and replace them with % characters. Not too bad, except when you think about all of the ways that periods can be used (decimal points in numbers, filenames in include statements, punctuation in comments, Fortran 77 relational operators, maybe others). I've done some preprocessing to fix the relational operators to use the Fortran 90 symbols, and I don't really care about mangling the grammar of comments, but I haven't come up with a good approach to translate the . to % for the cases above. It seems like I should be able to do this with sed, but I'm not sure how to match the instances I need to fix. Here are the rules that I've thought of:
On a line-by-line basis:
If the line begins with <whitespace>include, then we shouldn't do anything to that line; pass it through to the output, so we don't mess up the filename inside the include statement.
The following strings are operators that don't have symbolic equivalents, so they must be left alone: .not. .and. .or. .eqv. .neqv.
Otherwise, if we find a period that is surrounded by 2 non-numeric characters (so it's not a decimal point), then it should be the operator that I'm looking to replace. Change that period to a %.
I'm not a native Fortran speaker myself, so here are some examples:
include 'file.inc' ! We don't want to do anything here. The line can
! begin with some amount of whitespace
if x == 1 .or. y > 2.0 ! In this case, we don't want to touch the periods that
! are part of the logical operator ".or.". We also don't
! want to touch the period that is the decimal point
! in "2.0".
if a.member < 4.0 .and. b.othermember == 1.0 ! We don't want to touch the periods
! inside the numbers, but we need to
! change the "a." and "b." to "a%"
! and "b%".
Any good way of tackling this problem?
Edit: I actually found some additional operators that contain a dot in them that don't have symbolic equivalents. I've updated the rule list above.
You can't do this with a regexp, and it's not that easy.
If I had to do what you have to, I would probably do it by hand, unless the codebase is huge. If the former applies, first replace all [a-zA-Z0-9].[a-zA-Z] to something very weird that is guaranteed never to compile, something like "#WHATEVER#", then proceed to search all these entries and replace them by hand after manual control.
If the amount of code is huge, then you need to write a parser. I would suggest you to use python to tokenize basic fortran constructs, but remember that fortran is not an easy language to parse. Work "per routine", and try to find all variable names used, using them as a filter. If you encounter something like a.whatever, and you know that a is in the list of local or global vars, apply the change.
Unless the codebase is really HUUGE (and do think very hard whether this is indeed the case), I'd just take an editor like Vim (vertical select & block select are your friends) a*nd set aside an afternoon to do this by hand*. In one afternoon, my guess is you'll be done with most of it, if not all. Afternoon is a lot of time. Just imagine how many cases you could've covered in these 2 hours alone.
Just by trying to write a parser for something like this, will take you much longer than that.
Of course, the question begs itself ... if the code if F77 which all compilers still support, and the code works ... why are you so keen on changing it?
I'm not that versed in regexps, so I guess I'd try tackling one this from other side. If you grep for the STRUCTURE keyword, you get the list of all the STRUCTURES used in the code. Once you have it, for each STRUCTURE S then you can just replace all instances of S. by S%.
This way you don't have to worry about things like .true., .and., .neq. and their relatives. The main worry then would be to be able to parse the STRUCTURE declarations.
Although the regex below :
(?<!')\b([^.\s]+)(?<!\.(?:not|and|or|eqv|neqv))(?<=\D)\.(?=\D)(?!(?:not|and|or|eqv|neqv)\.)([^.\s]+)\b(?!')
Replace $1%$2
Works perfectly for your examples, I would not recommend using it with your current task. It will definitely not cover all your cases. Now if you care for a 80% coverage or something you could use it but you should probably back up your sources. With the limited set of input cases I had , I am sure that there will be cases that the regex would replace something that it shouldn't.
Good luck :)
This sed oneliner might be a start
sed -r '/^\s*include/b;/^\s*! /b;G;:a;s/^(\.(not|and|or|eqv|neqv)\.)(.*\n.*)/\3\1/;ta;s/^\.([^0-9]{2,})(.*\n.*)/\2%\1/;ta;s/^(.)(.*\n.*)/\2\1/;ta;s/\n//'
Based on your examples, I am guessing it would be enough to protect quoted strings, then replace periods with alphabetics on both sides.
perl -pe '1 while s%(\x27[^\x27]+)\.([^\x27]+\x27)%$1##::##$2%;
s/([a-z])\.([a-z])/$1%$2/g;
s/##::##/./g' file.f
I offer this Perl solution not because sed is not a good enough tool for this, but because it avoids the issue of minor but pesky differences between sed dialects. The ability to use a hex code for the single quotes is a nice bonus.
Suppose I want to overload operator<< for an optional<T> class template. How would I print the "absent value", and how would I print a "real value" x?
none
some x
or
[]
[x]
Or should I literally print nothing for the first case and x for the second? How is this normally handled?
I like the option of print None and Some x. I think that this immediately describes what's going on (especially for people familiar with Haskell).
Personally, I would not use the [] and [x] alternative, because many languages use the square brackets to denote some sort of list. If I were to see that output, I would immediately be thinking that a list had been printed, as opposed to an optional type.
In the absence of any context, I would think of an optional as a special case of a collection, that either is empty or has one member.
You probably already have a convention for how to print collections or compound objects, but something like {} if it's empty or {x} if it has the value x would seem reasonable. If you print out an empty vector as none and a vector with three elements as some x y z, then by all means apply the same convention to an optional type :-)
I'm not aware of any specific convention. Personally I'd print (null) when the value is missing and the actual value otherwise.
It depends on the type. If you want a string to be printed, it could be "" or "Fred". If it is an array, it could be {} or { 1, 2, 3 }.
Following this video or the code attached in the web page can help you. Pretty Printer
The choice of behavior should probably be based on why you're implementing an output operator. If it is mostly for debugging purposes it is important to provide a visual clue that a value is missing. Printing an existing value between square brackets or just the open and closed brackets if the value is missing is a valid approach, given that square brackets are often used to indicate optionality, e.g. in command help messages.
On the other hand if this is meant to be a general purpose output operator the best approach is probably to print existing values as you would for the non-optional underlying type and the empty string for missing values.
The UNIX and the Echo.
There dwelt in the land of New Jersey the UNIX, a fair maid whom savants traveled far to admire. Dazzled by her purity, all sought to expose her, one for her virginal grace, another polished civility, yet another for her agility in performing exacting tasks seldom accomplished even in much richer lands. So large of heart and accomodating of nature was she that the UNIX adopted all but the unsufferably rich of her suitors. Soon many offspring grew and prospered and spread to the ends of the earth.
Nature herself smiled and answered to the UNIX more eagerly than to other mortal beings. Humbler folk, who knew little of more courtly manners, delighted in her echo, so precise and crystal clear they scarce believed she could be answered by the same rocks and woods that so garbled their own shouts into the wilderness. And the compliant UNiX obliged with perfect echoes of what ever she was asked. When one impatient swain asked the UNIX, 'Echo nothing', the UNIX obligingly opened her mouth, echoed nothing, and closed it again.
'Whatever do you mean,' the youth demanded, 'opening your mouth like that? Henceforth never open your mouth when you are supposed to echo nothing!' And the UNIX obliged.
'But I want a perfect performance, even when you echo nothing,' pleaded a sensitive youth, 'and no echoes can come from a closed mouth.' Not wishing to offend either one, the UNIX agreed to say different nothings for the impatient youth and the sensitive youth. She called the sensitive nothing '\n.'
Yet now when she said '\n,'she was really not saying nothing so she had to open her mouth twice, once to say '\n,' and once to say nothing, and so she did not please the sensitive youth, who said forthwith, 'The \n sounds like a perfect nothing to me, but the second ruins it. I want you to take back one of them.' So the UNiX, who could not abide offending, agreed to undo some echoes and called that '\c'. Now the sensitive youth could hear a perfect echo of nothing by asking for '\n' and '\c' together.
But they say that he died of a surfeit of notation before he ever heard one.
-- Doug McIlroy