What Kind of Integer Array is produced by this Format? - fortran

I'm new to FORTRAN and need to work with a code to read and write Data. The Code is a bit older and I need to understand how things happen inside ;)
The code reads a Line of a .dat file with the
FORMAT(36A2):
READ(11,FORMAT(36A2)) ITEXT
The variable ITEXT is declared as an Integer array:
INTEGER(KIND=2), DIMENSION(36) :: ITEXT
So if I read in the following line:
SREF = 0.031416,
ITEXT hast the following value:
2313 8224 21075 17989 8224 15648 12320 12334 12595 12596 11318 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224 8224
If I do WRITE(11,FORMAT(36A2)) it gives me back my Full Text.
SREF = 0.031416,
So what is this Kind of "Integer Code"?
How can I work with it and why should I use it?
It is completely new to me.
In the following part is an example Code. The integer "21075" represents "SR" of "SREF = 0.031416"
program example
integer :: ITEXT = 21075
WRITE (*,100), ITEXT
100 FORMAT(36A2)
end program example

There was no character datatype in the original Fortran. Chracter data had to be stored in integers. Character strings could be stored in there using the obsolete Hollerith constants
ITEXT = 2HSR
This stores two characters "SR" in ITEXT. Now a better way is to use read to store it there
WRITE(ITEXT,'(A2)') "SR"
or
WRITE(ITEXT,'("SR")')
The format itself
100 FORMAT(36A2)
is an ordinary string input/output format. It outputs 36 strings of length two. Typically it is applied to string data, but it can be applied to other data types as well if character data is stored in them. If the numeric data types actually contain numeric data, the output from the character format will be garbage.
Be aware that the literal constant 2 in (KIND=2) is not portable and is not guaranteed to be the right one to store two characters (unlike the non-standard INTEGER*2). See Fortran: integer*4 vs integer(4) vs integer(kind=4)

The code represents a really old fortran style. The characters of the string are encoded as the decimal values of the ASCII table into the integer elements of the array itext. As the code read the character string with the format A2 two characters of the input from the file are stored into each array element. The numerical value that results in any element will be:
ASCII_1*2**8 + ASCII_2
where ASCII_1 and ASCII_2 are the two decimal entries of the characters in the ASCII table.
As the first two characters are ' ' (blanks) with ASCII value 32, you get
32*2**8 + 32 = 8224
Try out your program with this
program bla
integer(KIND=1), DIMENSION(72) :: itext
open(11,file='bla.dat',status='old')
read(11,'(72a1)') itext
write(*,'(72a1)') itext
write(*,'(72(i4,2x))') itext
close(11)
end program bla
you will then get a string of numbers like 32 for a ' ', 83 for a 'S' etc.

Related

Casting an int to a char. Not storing the correct value

I'm trying to store a number as a character in a char vector named code
code->at(i) = static_cast<char>(distribution(generator));
However it is not storing the way I think it should
for some shouldn't '\x4' be the ascii value for 4? if not how do I achieve that result?
Here's another vector who's values were entered correctly.
You are casting without actually converting the int to a char. You need:
code->at(i) = distribution(generator) + '0';
No. \xN does not give you the ASCII code for the character N.
\xN is the ASCII character† whose code is N (in hexadecimal form).
So, when you write '\x4', you get the [unprintable] character with the ASCII code 4. Upon conversion to an integer, this value is still 4.
If you wanted the ASCII character that looks like 4, you'd write '\x34' because 34 is 4's ASCII code. You could also get there using some magic, based on numbers in ASCII being contiguous and starting from '0':
code->at(i) = '0' + distribution(generator);
† Ish.

Unknown integer conversion for string length >10 in cocos2d/Xcode applications(iOS 7.0)

I am working with cocos2d 2.0 and iOS7.0. And while trying to get the integer value or float value of a string with larger length(usually > 10), I'm always getting some unknown outputs as below:
when string length <= 10:
NSString *amount = #"1234567890";
NSLog(#"AmountStr=|%#|",amount);
NSLog(#"Amount =|%d|",[amount integerValue]);
Output(getting correct integer value):
AmountStr=|1234567890|
Amount =|1234567890| --
But, when string length >10, that is :
NSString *amount = #"12345678901"; -- added a '1' after the string, so length = 11
NSLog(#"AmountStr=|%#|",amount);
NSLog(#"Amount =|%d|",[amount integerValue]);
then I am getting the output as :
AmountStr=|12345678901| -- This is correct
Amount =|2147483647| -- But what about this..!!! :O
I have tried integerValue, intValue, and floatValue. Every time, same error occurs. So how do I findout the int value of a string with length greater than 10. Please help me.
NSLog(#"Amount =|%lli|",[amount longLongValue]);
You're trying to print a number as an integer which is larger than the largest number an integer can hold. It's not even about number of digits. Trying to do this with 3000000000 would replicate the "error".
There's also doubleValue method for NSString, which will give you more significant digits than floatValue.
Moreover, I'm a little surprised that using %d with the call to integerValue even works. intValue returns an int. But integerValue returns an NSInteger. Normally, when using format specifiers with NSInteger, you need to use %ld and cast the NSInteger to a long...
And for up to 38-digits, you can always use NSDecimalNumber.
NSDecimalNumber *myNum = [NSDecimalNumber decimalNumberWithString:amount];
NSLog(#"%#", [myNum descriptionWithLocale:[NSLocale systemLocale]]);

How can i convert an integer value into its corresponding hex and store it in a single byte variable using C language

How can i convert an integer value into its corresponding hex and store it in a single byte variable using C language.
int nVar = 24; // where hex value 0x18
BYTE byRes;
char sBuff[8] = {0};
sprintf(sBuff, "%x", nVar);
Where sBuff[0] = 0x30 and sBuff[1] = 0x38 but this is not what i am looking for. I want to save the hex value of nVar in byRes variable.
Thanks
Note that "decimal" or "hex" is only a representation of an numeric value. In other words, these are different ways of displaying an int on the screen. Assigning byRes = (BYTE)nVar; copies the value of nVar to byRes. You can display that value as hex or decimal or base-7 or base-42 if you want. Modern computers store data as differences in voltage. At the machine level, we often think of these as in terms of "high" and "low" or "0" and "1" (aka binary), but at the programming level, we can think of these numeric values any way we wish. Assigning a "hex" value from one variable to another is the same as assigning the "decimal" value because the computer does not know how we think about the value until we ask it to display it. When you do this (e.g. with a printf() call), the computer converts the values to ASCII characters which are no longer really the integral value which we are manipulating.
All numbers (and everything else) in C is represented as binary digits. The value of 0x18 and 24 are one and the same. It only matters when you want to represent them as strings.

Extracting string data from text C++

Im currently writing a c++ program that needs to extract string and numeric data from a text file. The format of the data is the following;
3225 C9+ ELECTR C8 C * 1.00E-6 -0.30 0.0
first entry is an integer, next 5 entries are strings and the last 3 are floats. No string is ever greater than 7 characters long.
I am reading the file line by line and then extracting the data using;
sscanf(ln.c_str(),"%d %s %s %s %s %s %e %e %e",
&rref[numre],&names[numre][0],&names[numre][1],&names[numre][2],&names[numre][3],
&names[numre][4],&nums[numre][0],&nums[numre][1],&nums[numre][2]);
this works fine untill I meet a line like;
3098 SIC2H3+ ELECTR SIC2H2 H * 1.50E-7 -0.50 0.0
where one of the entrys is the full 7 characters long. In this case I get;
names[3097][0] = "SIC2H3+ELECTR"
and,
names[3097][1] = "ELECTR"
Anybody got any ideas...they will be much appreciated!!
The most likely problem is in the declaration of names: if you declared it as holding seven characters or less, and forgot to allocate space for terminating zero, you'd get the results that you are describing.
char names[MAX][4][7]
will have enough space for strings of length 6 or less; for strings of length 7, you need
char names[MAX][4][8]

Concatenate two integers

What is the best way to concatenate two integers to an integer in Fortran?
integer a = 999
integer b = 1111
integer c should be 9991111
Thanks,
SM.
Here is an example code that does what you need. It writes integers into character strings, trims and concatenetes them, and then reads the result integer from concatenated character string:
integer :: a,b,c
character(len=99) :: char_a,char_b,char_c
a = 999
b = 1111
write(unit=char_a,fmt=*)a
write(unit=char_b,fmt=*)b
char_c = trim(adjustl(char_a))//trim(adjustl(char_b))
read(unit=char_c,fmt=*)c
print*,c
end
Edit: Note that this example is general for any integer lengths, assuming they fit into their respective kind (no integer overflow).
You can use the information of the order of the number:
integer :: a = 999
integer :: b = 1111
integer :: c
c = a * 10**(ceiling(log10(real(b)))) + b
write(*,*) c
Your best bet is to use internal files to convert your two integers to a character, and then convert this back to an integer.
There is no intrinsic procedure for converting a numeric value to a character/string representation. See this discusson on Fortran Wiki for more information (see the part headed "Note").
As an example, in your case you could use the following:
program test_conversion
implicit none
integer :: a=999
integer :: b=1111
integer :: c
character(len=7) :: temp
write(temp, '(i3.3, i4.4)') a, b ! You may need to change these format specifiers
read(temp, *) c
print*, c ! This prints 9991111
end program test_conversion
You will have to change the format string if you want different widths of the character representation of your integers.