4

just trying to write a simple program to find the gcd of n numbers. I have no clue how to fix this error, i've read all of octaves function documentation and tried to find questions like this ... Just started programming in Octave btw. Here's the code:

function divisor = gcd(x, y)
  q=0;
  r=0;
  l=0;
  h=0;
  if(x>y)
    h=x;
    l=y;
 elseif(x<y) 
    h=y;
    l=x;
 else
    h=y;
    l=x;
 endif 
 while(r != 0)
    q=floor(h/l);
    r = h-l*q;
    q=h;
    r=l;
 endwhile
 divisor = q;
 printf("%d", q);
 return;
endfunction

The Error:

error: 'x' undefined near line 6 column 6
error: called from
     gcd at line 6 column 3
desertnaut
  • 57,590
  • 26
  • 140
  • 166
lkat
  • 43
  • 1
  • 1
  • 5
  • Are you calling it from some other script or trying to run this file as it is? – Sardar Usama Jun 12 '17 at 21:07
  • Note you don't need brackets around if / while statments. Also, there's no need for a `return` statement at the end of the function. – Tasos Papastylianou Jun 13 '17 at 02:00
  • 1
    I was trying to run the file as is. But it's fixed now thanks to Marc.2377. – lkat Jun 13 '17 at 17:07
  • I noticed you had edited your question to correct the code according to the answer given; that should not be done, otherwise newcomers won't be able to figure what was wrong. It's now been reverted. – Marc.2377 Jul 14 '18 at 22:43

2 Answers2

5

Your code is a function definition. Your function is called gcd.

You have to save your code in a file called gcd.m and then create a new file so that you can call that function from it.

In the same directory you have saved gcd.m, create a file (for example: gcdtest.m) and put the following code in it:

test = gcd(40, 50)

Then save and run this file. If the output doesn't work as expected, restarting Octave should fix it.

The numbers I've chosen are only an example.


Explanation:

If all you have is the function definition file (i.e. gcd.m), when you hit "Save and run", Octave will itself call your function, but it's not clever enough and won't use any parameters in doing so. That's why you get an "undefined variable" error. That would be similar to you having only test = gcd() in your test file.

If, however, you call the function with the arguments, they will initialize the variables x and y correctly and your code will work.

You can also simply call gcd(40, 50) from the Octave command line, for testing purposes.

The following are links to the Octave documentation regarding functions and function files (I know you said you read them, but newcomers might not have):

https://www.gnu.org/software/octave/doc/interpreter/Defining-Functions.html

https://www.gnu.org/software/octave/doc/interpreter/Function-Files.html


Now, I noticed a couple of issues in your code:

  • while(r != 0) on line 16 - this won't run, not even once, since you define r as 0 in line 3 and don't assign a new value to it later.

  • elseif(x<y) (line 9) and else (line 12) both do exactly the same thing. It would be better to remove the elseif condition entirely and only have else instead.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Marc.2377
  • 7,807
  • 7
  • 51
  • 95
  • Just adding that you do not have to create the second m file, you can just call gcd from the command line using the text put into gcdtest.m . Beginners often don't recognize the difference. he gcd.m file is a function file, the gcdtest.m file is a script file, and script files are just lists of interpreter commands. – Nick J Jun 13 '17 at 03:25
  • 1
    Thank you very much, all fixed. I noticed another problem too : instead of q=h;r=l; It should be h=q;l=r; - In the while loop. – lkat Jun 13 '17 at 17:00
  • I normally name a function the same as the filename, and then call my functions from inside that. I think about it like void main(). – Luke Dupin Jan 04 '19 at 21:18
  • @LukeDupin You probably already know this, but just thought it was worth mentioning that [`void main()` is not recommended in C and C++](https://stackoverflow.com/q/204476/3258851). – Marc.2377 Jan 09 '19 at 22:52
1

Octave assumes any code starting with the function keyword is a so-called "function file" that must only be called from a "script file". If you want to prevent this absurd confusion, just add anything above your code. For example:

1;
function foo = bar(baz)
    % do some stuff
end

More information here.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • Looking forward to seeing more people on [Octave's Discord channel](https://mail.gnu.org/archive/html/help-octave/2020-09/msg00010.html). – Foad S. Farimani Feb 16 '21 at 19:20