# Can a library function operating on a struct work for non “storage” structs?

I'm just getting started with solidity, and I'm working on a contract that calculates the periodic payment on an amortized loan. My goal is to implement the annuity formula: I've started a library for rational data and a struct for the fraction. In order for the library function to compile the function signature requires any struct parameters be marked with the `storage` keyword.

``````library Rational
{
struct FractionUint
{
uint numerator;
uint denominator;
}

function multiply(FractionUint storage self, FractionUint storage other)
{
self.numerator *= other.numerator;
self.denominator *= other.denominator;
}

...
}

contract testRational
{
using Rational for Rational.FractionUint;
Rational.FractionUint f1;
Rational.FractionUint f2;

function testMultiply()
{
f1 = Rational.FractionUint(1,10);
f2 = FractionUint(100,2);
f1.multiply(f2);
if (f1.numerator != 100)
throw;
if (f1.denominator != 20)
throw;
}

/*
function testMultiply2()
{
var f3 = Rational.FractionUint(1,10);
var f4 = Rational.FractionUint(100,2);
f3.multiply(f4);
if (f3.numerator != 100)
throw;
if (f3.denominator != 20)
throw;
}
*/
}
``````

Compiling testMultiply2 restults in the error:

Error: Member "multiply" is not available in struct FractionUint memory outside of storage.

There are multiple intermediate steps for which I'd like to use some variables defined in the scope of the contract function.

Can a library function called from a contract function perform operations on variables defined in the contract function scope?

Libraries can operate on structs in storage (that's one of their main purposes) but are currently unable to operate on memory structs (lifting this limitation is planned, though).

For your general problem concerning fractional numbers, I would propose different solutions, though:

1. either combine the two `uints` into a single `uint` (256 bits is a lot) or use `uint` instead of the struct
2. wait for Solidity to receive fixed point integers (they should come "soon")
• Excellent, I look forward to the fixed point types. I'll hold off until then. – Robert Graves Mar 8 '16 at 22:49

Sure you can using Solidity 0.5.x, just define a copy of the same function but with `memory` instead of `storage`:

``````function multiplyMemory(FractionUint memory self, FractionUint memory other) {
self.numerator *= other.numerator;
self.denominator *= other.denominator;
}
``````

I case of view methods, you can reuse `memory` method inside `storage` one, but be aware struct will we fulle loaded from storage:

``````function value(Data storage self) internal view returns(uint256) {
return valueMemory(self);
}

function valueMemory(Data memory self) internal view returns(uint256) {
return uint256(self.origin).mul(