Reading input files problem

Hi! I bougth a new Mac and I installed Xcode 10. I ran a c++ program which takes as input some .txt matrices but it can read only some of them. On my pc, which uses Xcode 8.1.0, and also on other computers with different operating systems, all the matrices are properly read. Is there something I have to change in the settings? The numers are read with double precision. The fact is that some of the matrices are read properly and other ones not, they are read as they are entirely formed by 0. In fact, they are mainly made by 0 but not entirely.

Replies

It’s hard to offer any opinions without knowing more about the code you’re using the read the matrix. Can you post a snippet of that code and an example of the text it’s failing to read?

Please format your code as a code block, using the

<>
icon, to make it easier for us to read.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for the reply. The reading code is the following (I give you an example with two matrices, because they are 28 in total):


<

#include <cstdlib>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <iostream>

#include <cmath>

#include <random>

#include <iomanip>

#include <fstream>

#include <gsl/gsl_interp.h>

#include <gsl/gsl_spline.h>


#define NR448 331

#define NZ448 326


#define NR7244 293

#define NZ7244 306


using namespace std;


int main()

{


double **jb448;

jb448=new double*[NR448+1];


for(i=0; i<=NR448; i++)

{

jb448[i]=new double[NZ448+1];

}


double **jb7244;

jb7244=new double*[NR7244+1];


for(i=0; i<=NR7244; i++)

{

jb7244[i]=new double[NZ7244+1];

}


ifstream infile448 ("jb448_newBC_1.txt");

{

for(i = 0; i <= NR448; i++)

{

for(k = 0; k <= NZ448; k++)

{

infile448>>jb448[i][k];

}

}

}


infile448.close();


cout<<"jb448["<<(NR448-1)/2<<"]["<<NZ448/2<<"] = "<<jb448[(NR448-1)/2][NZ448/2]<<endl<<endl;



ifstream infile7244 ("jb7244_newBC_1.txt");

{

for(i = 0; i <= NR7244; i++)

{

for(k = 0; k <= NZ7244; k++)

{

infile7244>>jb7244[i][k];

}

}

}


infile7244.close();


cout<<"jb7244["<<(NR7244-1)/2<<"]["<<NZ7244/2<<"] = "<<jb7244[(NR7244-1)/2][NZ7244/2]<<endl<<endl;



for(int i = 0; i <= NR448; i++)

{

delete[] jb448[i];

}

delete[] jb448;



for(int i = 0; i <= NR7244; i++)

{

delete[] jb7244[i];

}

delete[] jb7244;



return 0;

}

>


The correct output (that appears on my laptop and on the other computers I used) is


<

jb448[165][163] = 49.4531


jb7244[146][153] = 3.64542

>


instead on my new pc the following output appears:


<

jb448[165][163] = 49.4531


jb7244[146][153] = 0

>


So the first matrix is properly read whereas the second is not. I also cheked if it was only a problem of visualization but it reads the matrix in the wrog way (maybe as it is made entirely by 0).

Are you running this tool on the command line from the same directory where both of these files are located?


A common problem is people running command line tools in the debugger and not realizing that it is looking for such input files in whatever random "derived" directory that happens to be current at the time.

No, both the matrices are in the directory where my code is present. And I'm running from the command line from the same directory where my files are located. The only difference between my laptop and this new pc is that on the first I have Xcode 8.1.0 and on this I have Xcode 10.

You are going to have to clarify what you mean then. You said "I also cheked if it was only a problem of visualization but it reads the matrix in the wrog way (maybe as it is made entirely by 0)."


I'm not sure what you mean by visualization. You said you checked it. What does that mean. Then you said it reads the matrix in the wrong way? What does that mean? Did you debug the program and see what the values are while it is being read in? Are the values zero?


Finally, you said, "it is made entirely by 0". I assume that you mean something entirely different than what you said. Because you said the file is made entirely by zero. Therefore, your program should print out zero for all values in the matrix. So where's the problem?

No, the matrix is not made entirely by 0, it is only made mainly by 0. For example the point jb7244[146][153] is equal to 3.64542 but the computer reads it as it is a 0. The check I made was to understand if he printed on the terminal 0 but he effectively read the matrix properly or if it read the matrix in the wrong way.


Summarizing, the fact is that the computer read this matrix as it is made entirely by 0 but the matrix is not made entirely by 0. Moreover the computer reads some matrices in the correct way and other ones in the wrong way. I ask myself if this can depend on the installed version of Xcode.

I can assure you that the problem is not with Xcode. Instead of printing a single value from the matrix, I suggest you create a validation function that reads the matrix and then outputs a new copy. You can compare the original with the copy and see where the problem is.

I think that the problem is not with the matrix itself.


Copying the matrix from my laptop to this new pc the program does not import it. Then, I tried to generate the matrix directly on the new pc but it does not import it again. So I tried a final test: I did not import the matrix in the program but I generated it directly into the program, on the new pc. Analyzing the result, I understand that the matrix is properly defined. This means that the matrix is properly defined, both on my laptop and on the new pc, but there is a problem in the reading of the matrix that with some matrices works and with other ones it does not work. Do you think that the difference in the operating system is the cause of the problem?


I can also try to use the validation function as a filal check.

No. As I said before, the problem is in the file or in your code. I can't tell which. From the headers, it is clear that there is much more code than you have posted here.


Start with the basics. Write a program to read in the matrix and then write it back out in exactly the same format. Any problems should be easy to find and fix. Then you can add the rest of your code that does whatever you need to do.

Hi,

I wrote a code on my new Mac (Mojave 10.14.3) that reads in the matrix and writes it back in the same format (.txt). My input matrix has a dimension of 1.1 MB whereas the output matrix has a dimension of 181 KB, which means that I have lost many information. I checked and the files is made almost entirely by 0. I tried the same code (the read in - write out code) on my laptop (macOS Sierra 10.12.6) and on a Virtual Box with Ubuntu intalled on my new Mac with Mojave and it returns me a matrix with the correct dimension (1.1 MB). I have also made other tests to confirm that the input and output matrices are different on my new Mac whereas they are identical on my laptop and on the Virtual Box with Ubuntu. So, as I have also checked other times, the problem cannot be with the code itself but I suppose that there is a problem linked to the operating system, which is the only difference between the three machines. Can you give me any suggestions to solve this problem?

Thank you very much,

Valentina

the problem cannot be with the code itself but I suppose that there is a problem linked to the operating system, which is the only difference between the three machines.

There may well be a problem with the OS or the tools, but if you have any experience with C-based languages you’ll know that they leave a lot of scope for code that works in one environment but fails an another. Here’s a trivial example:

static int increment(int i) {
    i = ++i;
    return i;
}

If you can guarantee that your code contains no such problems, it’s worthwhile investigating issues with the OS and the tools. My experience, however, is that no significant C-based program is free from such problems. When faced with portability issues like this, the first step is to investigate the code, which is where the vast majority of such issues originate. Only once you’ve reduced the program to a sufficiently small test case that you can feasibly check it for code problems, is it worthwhile, IMO, investigating the OS and tools.

If you can further reduce your test project to something that I can reasonably run, I’d be happy to have a quick look.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ValeRG wrote:


Can you give me any suggestions to solve this problem?

If you feel that you have definitively proven that the cause is a compiler bug, then only Apple compiler engineers can fix the bug. Please file a bug report and include a sample project that reproduces the problem. You should expect your bug to be resolved within 2-8 years.


If you don't want to wait that long, then, as eskimo suggests, you could solve the problem by using some language other than C++.


If you don't want to rewrite the code, then you could use the debugger to isolate what is triggering the bug and use some kind of workaround.

[ValeRG sent me a test project via email]

I radically simplified your test case to use this file:

$ hexdump -Cv jb7244_newBC_1.txt 
00000000  35 2e 39 32 38 37 39 65  2d 33 32 33 0a           |5.92879e-323.|
0000000d

with this program:

using namespace std;

int main()
{
    ifstream infile7244 ("jb7244_newBC_1.txt");
    double tmp = 666.0;
    infile7244 >> tmp;
    printf("tmp: %g\n", tmp);
    printf("fail: %d\n", infile7244.fail());
    printf("%g\n", std::numeric_limits<double>::min());
    return 0;
}

It prints:

tmp: 5.92879e-323
fail: 1
2.22507e-308

I believe that the read fails because the value is too small to be represented by a

double
(the exponent is -323 where the minimum normalised
double
has an exponent of -308). I’m not enough of a C++ expert (hence my use of
printf
:-) to tell you whether that’s allowed by the standard or not, or whether there’s a standard way to configure this behaviour.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Apparently, there is such a thing as a "denormalized" or "subnormal" double. If you change that numeric_limits statement to "denorm_min" then it prints "4.94066e-324", the same as on Linux.


This Stack Overflow question describes the problem in detail, with respect to clang: https://stackoverflow.com/questions/52410931/why-does-clang-stdostream-write-a-double-that-stdistream-cant-read


It looks like clang's std library can write such a double, but then can't read it. I agree that should be considered a bug. Someone has already written a bug report on this issue: https://bugs.llvm.org/show_bug.cgi?id=39012


It was reported on 2018-09-20, so I'm willing to bet that my 2-8 year fix estimate is going to be pretty accurate.

So what's going on with moderation? I see people posting external links all the time now so I figured I could post them. I guess I can't. Here is a version of my previous post with the URLs corrupted.


Apparently, there is such a thing as a "denormalized" or "subnormal" double. If you change that numeric_limits statement to "denorm_min" then it prints "4.94066e-324", the same as on Linux.


This Stack Overflow question describes the problem in detail, with respect to clang: stackoverflow.com/questions/52410931/why-does-clang-stdostream-write-a-double-that-stdistream-cant-read


It looks like clang's std library can write such a double, but then can't read it. I agree that should be considered a bug. Someone has already written a bug report on this issue: bugs.llvm.org/show_bug.cgi?id=39012


It was reported on 2018-09-20, so I'm willing to bet that my 2-8 year fix estimate is going to be pretty accurate.